From 995a04679eb42ccdf4c8b751770ce9b3535f56e0 Mon Sep 17 00:00:00 2001 From: defelmnq Date: Thu, 14 Nov 2024 07:06:46 +0100 Subject: [PATCH 01/12] feat(provisioners) - add endpoint to fetch tags associated to a key using its id fix: change from database.StringMap to codersdk.ProvisionerKeyTags in endpoint response improve annotations for endpoint move logic to enterprise part generate new doc move logic to enterprise part generate doc --- coderd/apidoc/docs.go | 37 +++++++++++++++++++++++ coderd/apidoc/swagger.json | 33 ++++++++++++++++++++ codersdk/provisionerdaemons.go | 18 +++++++++++ docs/reference/api/enterprise.md | 36 ++++++++++++++++++++++ enterprise/coderd/coderd.go | 1 + enterprise/coderd/provisionerkeys.go | 17 +++++++++++ enterprise/coderd/provisionerkeys_test.go | 35 +++++++++++++++++++++ 7 files changed, 177 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 983abb61169c9..47b2093bfd2b2 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -3091,6 +3091,43 @@ const docTemplate = `{ } } }, + "/organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get provisioner key tags by ID", + "operationId": "get-provisioner-key-tags-by-id", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Provisioner Key ID", + "name": "provisionerkeyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerKeyTags" + } + } + } + } + }, "/organizations/{organization}/provisionerkeys/{provisionerkey}": { "delete": { "security": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 67cc92c71331d..2152aba0589ae 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -2715,6 +2715,39 @@ } } }, + "/organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags": { + "get": { + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get provisioner key tags by ID", + "operationId": "get-provisioner-key-tags-by-id", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Provisioner Key ID", + "name": "provisionerkeyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerKeyTags" + } + } + } + } + }, "/organizations/{organization}/provisionerkeys/{provisionerkey}": { "delete": { "security": [ diff --git a/codersdk/provisionerdaemons.go b/codersdk/provisionerdaemons.go index 7b14afbbb285a..22ec9228f0565 100644 --- a/codersdk/provisionerdaemons.go +++ b/codersdk/provisionerdaemons.go @@ -368,6 +368,24 @@ func (c *Client) ListProvisionerKeys(ctx context.Context, organizationID uuid.UU return resp, json.NewDecoder(res.Body).Decode(&resp) } +// GetProvisionTagsByKey returns the provisioner tags associated with the provisioner key. +func (c *Client) GetProvisionTagsByKey(ctx context.Context, organizationID uuid.UUID, provisionerKey string) (ProvisionerKeyTags, error) { + res, err := c.Request(ctx, http.MethodGet, + fmt.Sprintf("/api/v2/organizations/%s/provisionerkeys/%s/tags", organizationID.String(), provisionerKey), + nil, + ) + if err != nil { + return nil, xerrors.Errorf("make request: %w", err) + } + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + return nil, ReadBodyAsError(res) + } + var resp ProvisionerKeyTags + return resp, json.NewDecoder(res.Body).Decode(&resp) +} + // ListProvisionerKeyDaemons lists all provisioner keys with their associated daemons for an organization. func (c *Client) ListProvisionerKeyDaemons(ctx context.Context, organizationID uuid.UUID) ([]ProvisionerKeyDaemons, error) { res, err := c.Request(ctx, http.MethodGet, diff --git a/docs/reference/api/enterprise.md b/docs/reference/api/enterprise.md index 17f55afcddd81..a0b87d16e6973 100644 --- a/docs/reference/api/enterprise.md +++ b/docs/reference/api/enterprise.md @@ -1750,6 +1750,42 @@ Status Code **200** To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Get provisioner key tags by ID + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags \ + -H 'Accept: application/json' +``` + +`GET /organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags` + +### Parameters + +| Name | In | Type | Required | Description | +| ------------------ | ---- | ------------ | -------- | ------------------ | +| `organization` | path | string | true | Organization ID | +| `provisionerkeyid` | path | string(uuid) | true | Provisioner Key ID | + +### Example responses + +> 200 Response + +```json +{ + "property1": "string", + "property2": "string" +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags) | + ## Delete provisioner key ### Code samples diff --git a/enterprise/coderd/coderd.go b/enterprise/coderd/coderd.go index 03d535f6ffb69..b46516265f289 100644 --- a/enterprise/coderd/coderd.go +++ b/enterprise/coderd/coderd.go @@ -352,6 +352,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) { r.Use( httpmw.ExtractProvisionerKeyParam(options.Database), ) + r.Get("/tags", api.fetchProvisionerKeyTags) r.Delete("/", api.deleteProvisionerKey) }) }) diff --git a/enterprise/coderd/provisionerkeys.go b/enterprise/coderd/provisionerkeys.go index 0d153ffef1791..83e4a5e77865b 100644 --- a/enterprise/coderd/provisionerkeys.go +++ b/enterprise/coderd/provisionerkeys.go @@ -200,6 +200,23 @@ func (api *API) deleteProvisionerKey(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusNoContent, nil) } +// @Summary Get provisioner key tags by ID +// @ID get-provisioner-key-tags-by-id +// @Produce json +// @Tags Enterprise +// @Param organization path string true "Organization ID" +// @Param provisionerkeyid path string true "Provisioner Key ID" format(uuid) +// @Success 200 {object} codersdk.ProvisionerKeyTags +// @Router /organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags [get] +func (api *API) fetchProvisionerKeyTags(rw http.ResponseWriter, r *http.Request) { + var ( + ctx = r.Context() + pk = httpmw.ProvisionerKeyParam(r) + ) + + httpapi.Write(ctx, rw, http.StatusOK, codersdk.ProvisionerKeyTags(pk.Tags)) +} + func convertProvisionerKeys(dbKeys []database.ProvisionerKey) []codersdk.ProvisionerKey { keys := make([]codersdk.ProvisionerKey, 0, len(dbKeys)) for _, dbKey := range dbKeys { diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index d3615c1ccc931..8cb13fdafa368 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -133,3 +133,38 @@ func TestProvisionerKeys(t *testing.T) { err = orgAdmin.DeleteProvisionerKey(ctx, owner.OrganizationID, codersdk.ProvisionerKeyNamePSK) require.ErrorContains(t, err, "reserved") } + +func TestProvisionerKeyTags(t *testing.T) { + t.Parallel() + t.Run("GetTags", func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong*10) + t.Cleanup(cancel) + dv := coderdtest.DeploymentValues(t) + client, owner := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + DeploymentValues: dv, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureMultipleOrganizations: 1, + }, + }, + }) + + //nolint:gocritic // Not the purpose of this test + _, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ + Name: "key", + Tags: map[string]string{"key1": "value1", "key2": "value2"}, + }) + require.NoError(t, err) + + tags, err := client.GetProvisionTagsByKeyID(ctx, owner.OrganizationID, "key") + require.NoError(t, err) + require.Equal(t, tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) + + err = client.DeleteProvisionerKey(ctx, owner.OrganizationID, "invalid_key") + require.ErrorContains(t, err, "Resource not found") + }) +} From 2ca6c91dd17d9ddf1f5c36442b6b0894b7ab2fa9 Mon Sep 17 00:00:00 2001 From: defelmnq Date: Thu, 14 Nov 2024 08:12:19 +0000 Subject: [PATCH 02/12] rename function --- codersdk/provisionerdaemons.go | 4 ++-- enterprise/coderd/provisionerkeys_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/codersdk/provisionerdaemons.go b/codersdk/provisionerdaemons.go index 22ec9228f0565..431cce742e973 100644 --- a/codersdk/provisionerdaemons.go +++ b/codersdk/provisionerdaemons.go @@ -368,8 +368,8 @@ func (c *Client) ListProvisionerKeys(ctx context.Context, organizationID uuid.UU return resp, json.NewDecoder(res.Body).Decode(&resp) } -// GetProvisionTagsByKey returns the provisioner tags associated with the provisioner key. -func (c *Client) GetProvisionTagsByKey(ctx context.Context, organizationID uuid.UUID, provisionerKey string) (ProvisionerKeyTags, error) { +// FetchProvisionerTagsTagsByKey returns the provisioner tags associated with the provisioner key. +func (c *Client) FetchProvisionerTagsTagsByKey(ctx context.Context, organizationID uuid.UUID, provisionerKey string) (ProvisionerKeyTags, error) { res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/provisionerkeys/%s/tags", organizationID.String(), provisionerKey), nil, diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 8cb13fdafa368..7d020368b1546 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -160,11 +160,11 @@ func TestProvisionerKeyTags(t *testing.T) { }) require.NoError(t, err) - tags, err := client.GetProvisionTagsByKeyID(ctx, owner.OrganizationID, "key") + tags, err := client.FetchProvisionerTagsTagsByKey(ctx, owner.OrganizationID, "key") require.NoError(t, err) require.Equal(t, tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) - err = client.DeleteProvisionerKey(ctx, owner.OrganizationID, "invalid_key") + tags, err = client.FetchProvisionerTagsTagsByKey(ctx, owner.OrganizationID, "invalid_key") require.ErrorContains(t, err, "Resource not found") }) } From c67d3227e930f09193b26ec438560e3cc938cd5a Mon Sep 17 00:00:00 2001 From: defelmnq Date: Thu, 14 Nov 2024 08:16:55 +0000 Subject: [PATCH 03/12] linter --- enterprise/coderd/provisionerkeys.go | 2 +- enterprise/coderd/provisionerkeys_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/enterprise/coderd/provisionerkeys.go b/enterprise/coderd/provisionerkeys.go index 83e4a5e77865b..4a7928025b462 100644 --- a/enterprise/coderd/provisionerkeys.go +++ b/enterprise/coderd/provisionerkeys.go @@ -208,7 +208,7 @@ func (api *API) deleteProvisionerKey(rw http.ResponseWriter, r *http.Request) { // @Param provisionerkeyid path string true "Provisioner Key ID" format(uuid) // @Success 200 {object} codersdk.ProvisionerKeyTags // @Router /organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags [get] -func (api *API) fetchProvisionerKeyTags(rw http.ResponseWriter, r *http.Request) { +func (*API) fetchProvisionerKeyTags(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() pk = httpmw.ProvisionerKeyParam(r) diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 7d020368b1546..fa4962c42fd07 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -164,7 +164,7 @@ func TestProvisionerKeyTags(t *testing.T) { require.NoError(t, err) require.Equal(t, tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) - tags, err = client.FetchProvisionerTagsTagsByKey(ctx, owner.OrganizationID, "invalid_key") + _, err = client.FetchProvisionerTagsTagsByKey(ctx, owner.OrganizationID, "invalid_key") require.ErrorContains(t, err, "Resource not found") }) } From 911a47ddb7f78a9bb45d9a1e18ab1375c9137d2c Mon Sep 17 00:00:00 2001 From: defelmnq Date: Thu, 14 Nov 2024 08:20:20 +0000 Subject: [PATCH 04/12] linter --- codersdk/provisionerdaemons.go | 4 ++-- enterprise/coderd/provisionerkeys_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/codersdk/provisionerdaemons.go b/codersdk/provisionerdaemons.go index 431cce742e973..55b34e72953db 100644 --- a/codersdk/provisionerdaemons.go +++ b/codersdk/provisionerdaemons.go @@ -368,8 +368,8 @@ func (c *Client) ListProvisionerKeys(ctx context.Context, organizationID uuid.UU return resp, json.NewDecoder(res.Body).Decode(&resp) } -// FetchProvisionerTagsTagsByKey returns the provisioner tags associated with the provisioner key. -func (c *Client) FetchProvisionerTagsTagsByKey(ctx context.Context, organizationID uuid.UUID, provisionerKey string) (ProvisionerKeyTags, error) { +// FetchProvisionerTagsByKey returns the provisioner tags associated with the provisioner key. +func (c *Client) FetchProvisionerTagsByKey(ctx context.Context, organizationID uuid.UUID, provisionerKey string) (ProvisionerKeyTags, error) { res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/provisionerkeys/%s/tags", organizationID.String(), provisionerKey), nil, diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index fa4962c42fd07..8ba2b4ef1f711 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -160,11 +160,11 @@ func TestProvisionerKeyTags(t *testing.T) { }) require.NoError(t, err) - tags, err := client.FetchProvisionerTagsTagsByKey(ctx, owner.OrganizationID, "key") + tags, err := client.FetchProvisionerTagsByKey(ctx, owner.OrganizationID, "key") require.NoError(t, err) require.Equal(t, tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) - _, err = client.FetchProvisionerTagsTagsByKey(ctx, owner.OrganizationID, "invalid_key") + _, err = client.FetchProvisionerTagsByKey(ctx, owner.OrganizationID, "invalid_key") require.ErrorContains(t, err, "Resource not found") }) } From 1a019bb254016c1bf79fbb22b392dcf4156e5357 Mon Sep 17 00:00:00 2001 From: defelmnq Date: Thu, 14 Nov 2024 08:35:14 +0000 Subject: [PATCH 05/12] generate doc --- coderd/apidoc/docs.go | 46 ++++++++++--------- coderd/apidoc/swagger.json | 44 +++++++++--------- docs/reference/api/enterprise.md | 67 +++++++++++++++------------- enterprise/coderd/provisionerkeys.go | 5 ++- 4 files changed, 87 insertions(+), 75 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 47b2093bfd2b2..1a11de044a852 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -3091,16 +3091,18 @@ const docTemplate = `{ } } }, - "/organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags": { - "get": { - "produces": [ - "application/json" + "/organizations/{organization}/provisionerkeys/{provisionerkey}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } ], "tags": [ "Enterprise" ], - "summary": "Get provisioner key tags by ID", - "operationId": "get-provisioner-key-tags-by-id", + "summary": "Delete provisioner key", + "operationId": "delete-provisioner-key", "parameters": [ { "type": "string", @@ -3111,35 +3113,34 @@ const docTemplate = `{ }, { "type": "string", - "format": "uuid", - "description": "Provisioner Key ID", - "name": "provisionerkeyid", + "description": "Provisioner key name", + "name": "provisionerkey", "in": "path", "required": true } ], "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerKeyTags" - } + "204": { + "description": "No Content" } } } }, - "/organizations/{organization}/provisionerkeys/{provisionerkey}": { - "delete": { + "/organizations/{organization}/provisionerkeys/{provisionerkey}/tags": { + "get": { "security": [ { "CoderSessionToken": [] } ], + "produces": [ + "application/json" + ], "tags": [ "Enterprise" ], - "summary": "Delete provisioner key", - "operationId": "delete-provisioner-key", + "summary": "Get provisioner key tags by ID", + "operationId": "get-provisioner-key-tags-by-id", "parameters": [ { "type": "string", @@ -3150,15 +3151,18 @@ const docTemplate = `{ }, { "type": "string", - "description": "Provisioner key name", + "description": "Provisioner Key", "name": "provisionerkey", "in": "path", "required": true } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerKeyTags" + } } } } diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 2152aba0589ae..348624883c3b9 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -2715,12 +2715,16 @@ } } }, - "/organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags": { - "get": { - "produces": ["application/json"], + "/organizations/{organization}/provisionerkeys/{provisionerkey}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], "tags": ["Enterprise"], - "summary": "Get provisioner key tags by ID", - "operationId": "get-provisioner-key-tags-by-id", + "summary": "Delete provisioner key", + "operationId": "delete-provisioner-key", "parameters": [ { "type": "string", @@ -2731,33 +2735,30 @@ }, { "type": "string", - "format": "uuid", - "description": "Provisioner Key ID", - "name": "provisionerkeyid", + "description": "Provisioner key name", + "name": "provisionerkey", "in": "path", "required": true } ], "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerKeyTags" - } + "204": { + "description": "No Content" } } } }, - "/organizations/{organization}/provisionerkeys/{provisionerkey}": { - "delete": { + "/organizations/{organization}/provisionerkeys/{provisionerkey}/tags": { + "get": { "security": [ { "CoderSessionToken": [] } ], + "produces": ["application/json"], "tags": ["Enterprise"], - "summary": "Delete provisioner key", - "operationId": "delete-provisioner-key", + "summary": "Get provisioner key tags by ID", + "operationId": "get-provisioner-key-tags-by-id", "parameters": [ { "type": "string", @@ -2768,15 +2769,18 @@ }, { "type": "string", - "description": "Provisioner key name", + "description": "Provisioner Key", "name": "provisionerkey", "in": "path", "required": true } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerKeyTags" + } } } } diff --git a/docs/reference/api/enterprise.md b/docs/reference/api/enterprise.md index a0b87d16e6973..965955605394e 100644 --- a/docs/reference/api/enterprise.md +++ b/docs/reference/api/enterprise.md @@ -1750,66 +1750,69 @@ Status Code **200** To perform this operation, you must be authenticated. [Learn more](authentication.md). -## Get provisioner key tags by ID +## Delete provisioner key ### Code samples ```shell # Example request using curl -curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags \ - -H 'Accept: application/json' +curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/{provisionerkey} \ + -H 'Coder-Session-Token: API_KEY' ``` -`GET /organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags` +`DELETE /organizations/{organization}/provisionerkeys/{provisionerkey}` ### Parameters -| Name | In | Type | Required | Description | -| ------------------ | ---- | ------------ | -------- | ------------------ | -| `organization` | path | string | true | Organization ID | -| `provisionerkeyid` | path | string(uuid) | true | Provisioner Key ID | - -### Example responses - -> 200 Response - -```json -{ - "property1": "string", - "property2": "string" -} -``` +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | -------------------- | +| `organization` | path | string | true | Organization ID | +| `provisionerkey` | path | string | true | Provisioner key name | ### Responses -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags) | +| Status | Meaning | Description | Schema | +| ------ | --------------------------------------------------------------- | ----------- | ------ | +| 204 | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content | | -## Delete provisioner key +To perform this operation, you must be authenticated. [Learn more](authentication.md). + +## Get provisioner key tags by ID ### Code samples ```shell # Example request using curl -curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/{provisionerkey} \ +curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/{provisionerkey}/tags \ + -H 'Accept: application/json' \ -H 'Coder-Session-Token: API_KEY' ``` -`DELETE /organizations/{organization}/provisionerkeys/{provisionerkey}` +`GET /organizations/{organization}/provisionerkeys/{provisionerkey}/tags` ### Parameters -| Name | In | Type | Required | Description | -| ---------------- | ---- | ------ | -------- | -------------------- | -| `organization` | path | string | true | Organization ID | -| `provisionerkey` | path | string | true | Provisioner key name | +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | --------------- | +| `organization` | path | string | true | Organization ID | +| `provisionerkey` | path | string | true | Provisioner Key | + +### Example responses + +> 200 Response + +```json +{ + "property1": "string", + "property2": "string" +} +``` ### Responses -| Status | Meaning | Description | Schema | -| ------ | --------------------------------------------------------------- | ----------- | ------ | -| 204 | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content | | +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------------- | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags) | To perform this operation, you must be authenticated. [Learn more](authentication.md). diff --git a/enterprise/coderd/provisionerkeys.go b/enterprise/coderd/provisionerkeys.go index 4a7928025b462..5672e224af89a 100644 --- a/enterprise/coderd/provisionerkeys.go +++ b/enterprise/coderd/provisionerkeys.go @@ -202,12 +202,13 @@ func (api *API) deleteProvisionerKey(rw http.ResponseWriter, r *http.Request) { // @Summary Get provisioner key tags by ID // @ID get-provisioner-key-tags-by-id +// @Security CoderSessionToken // @Produce json // @Tags Enterprise // @Param organization path string true "Organization ID" -// @Param provisionerkeyid path string true "Provisioner Key ID" format(uuid) +// @Param provisionerkey path string true "Provisioner Key" // @Success 200 {object} codersdk.ProvisionerKeyTags -// @Router /organizations/{organization}/provisionerkeys/{provisionerkeyid}/tags [get] +// @Router /organizations/{organization}/provisionerkeys/{provisionerkey}/tags [get] func (*API) fetchProvisionerKeyTags(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() From c629f07f8a175e163086ff2a063028e413bb7685 Mon Sep 17 00:00:00 2001 From: defelmnq Date: Mon, 18 Nov 2024 13:38:28 +0000 Subject: [PATCH 06/12] changes endpoint to return all pk details --- codersdk/provisionerdaemons.go | 16 ++++---- enterprise/coderd/coderd.go | 10 ++++- enterprise/coderd/provisionerkeys.go | 49 +++++++++++++---------- enterprise/coderd/provisionerkeys_test.go | 20 ++++----- 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/codersdk/provisionerdaemons.go b/codersdk/provisionerdaemons.go index 55b34e72953db..011a59383a316 100644 --- a/codersdk/provisionerdaemons.go +++ b/codersdk/provisionerdaemons.go @@ -368,21 +368,23 @@ func (c *Client) ListProvisionerKeys(ctx context.Context, organizationID uuid.UU return resp, json.NewDecoder(res.Body).Decode(&resp) } -// FetchProvisionerTagsByKey returns the provisioner tags associated with the provisioner key. -func (c *Client) FetchProvisionerTagsByKey(ctx context.Context, organizationID uuid.UUID, provisionerKey string) (ProvisionerKeyTags, error) { +// GetProvisionerKey returns the provisioner key. +func (c *Client) GetProvisionerKey(ctx context.Context, pk string) (ProvisionerKey, error) { res, err := c.Request(ctx, http.MethodGet, - fmt.Sprintf("/api/v2/organizations/%s/provisionerkeys/%s/tags", organizationID.String(), provisionerKey), - nil, + fmt.Sprintf("/api/v2/provisionerkeys/%s", pk), nil, + func(req *http.Request) { + req.Header.Add(ProvisionerDaemonKey, pk) + }, ) if err != nil { - return nil, xerrors.Errorf("make request: %w", err) + return ProvisionerKey{}, xerrors.Errorf("make request: %w", err) } defer res.Body.Close() if res.StatusCode != http.StatusOK { - return nil, ReadBodyAsError(res) + return ProvisionerKey{}, ReadBodyAsError(res) } - var resp ProvisionerKeyTags + var resp ProvisionerKey return resp, json.NewDecoder(res.Body).Decode(&resp) } diff --git a/enterprise/coderd/coderd.go b/enterprise/coderd/coderd.go index b46516265f289..1b242f2b05137 100644 --- a/enterprise/coderd/coderd.go +++ b/enterprise/coderd/coderd.go @@ -339,6 +339,15 @@ func New(ctx context.Context, options *Options) (_ *API, err error) { r.Get("/", api.groupByOrganization) }) }) + r.Route("/provisionerkeys", func(r chi.Router) { + r.Use( + httpmw.ExtractProvisionerDaemonAuthenticated(httpmw.ExtractProvisionerAuthConfig{ + DB: api.Database, + Optional: false, + }), + ) + r.Get("/{provisionerkey}", api.getProvisionerKey) + }) r.Route("/organizations/{organization}/provisionerkeys", func(r chi.Router) { r.Use( apiKeyMiddleware, @@ -352,7 +361,6 @@ func New(ctx context.Context, options *Options) (_ *API, err error) { r.Use( httpmw.ExtractProvisionerKeyParam(options.Database), ) - r.Get("/tags", api.fetchProvisionerKeyTags) r.Delete("/", api.deleteProvisionerKey) }) }) diff --git a/enterprise/coderd/provisionerkeys.go b/enterprise/coderd/provisionerkeys.go index 5672e224af89a..9f3e7dfac74cf 100644 --- a/enterprise/coderd/provisionerkeys.go +++ b/enterprise/coderd/provisionerkeys.go @@ -200,35 +200,42 @@ func (api *API) deleteProvisionerKey(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusNoContent, nil) } -// @Summary Get provisioner key tags by ID -// @ID get-provisioner-key-tags-by-id -// @Security CoderSessionToken +// @Summary Get provisioner key details +// @ID get-provisioner-key +// @Security CoderProvisionerDaemonKey // @Produce json // @Tags Enterprise -// @Param organization path string true "Organization ID" // @Param provisionerkey path string true "Provisioner Key" -// @Success 200 {object} codersdk.ProvisionerKeyTags -// @Router /organizations/{organization}/provisionerkeys/{provisionerkey}/tags [get] -func (*API) fetchProvisionerKeyTags(rw http.ResponseWriter, r *http.Request) { - var ( - ctx = r.Context() - pk = httpmw.ProvisionerKeyParam(r) - ) - - httpapi.Write(ctx, rw, http.StatusOK, codersdk.ProvisionerKeyTags(pk.Tags)) +// @Success 200 {object} codersdk.ProvisionerKey +// @Router provisionerkeys/{provisionerkey} [get] +func (*API) getProvisionerKey(rw http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + pk, ok := httpmw.ProvisionerKeyAuthOptional(r) + // extra check but this one should never happen as it is covered by the auth middleware + if !ok { + httpapi.Forbidden(rw) + return + } + + httpapi.Write(ctx, rw, http.StatusOK, convertProvisionerKey(pk)) +} + +func convertProvisionerKey(dbKey database.ProvisionerKey) codersdk.ProvisionerKey { + return codersdk.ProvisionerKey{ + ID: dbKey.ID, + CreatedAt: dbKey.CreatedAt, + OrganizationID: dbKey.OrganizationID, + Name: dbKey.Name, + Tags: codersdk.ProvisionerKeyTags(dbKey.Tags), + // HashedSecret - never include the access token in the API response + } } func convertProvisionerKeys(dbKeys []database.ProvisionerKey) []codersdk.ProvisionerKey { keys := make([]codersdk.ProvisionerKey, 0, len(dbKeys)) for _, dbKey := range dbKeys { - keys = append(keys, codersdk.ProvisionerKey{ - ID: dbKey.ID, - CreatedAt: dbKey.CreatedAt, - OrganizationID: dbKey.OrganizationID, - Name: dbKey.Name, - Tags: codersdk.ProvisionerKeyTags(dbKey.Tags), - // HashedSecret - never include the access token in the API response - }) + keys = append(keys, convertProvisionerKey(dbKey)) } slices.SortFunc(keys, func(key1, key2 codersdk.ProvisionerKey) int { diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 8ba2b4ef1f711..62852819fadcd 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -134,12 +134,12 @@ func TestProvisionerKeys(t *testing.T) { require.ErrorContains(t, err, "reserved") } -func TestProvisionerKeyTags(t *testing.T) { +func TestProvisionerKey(t *testing.T) { t.Parallel() - t.Run("GetTags", func(t *testing.T) { + t.Run("GetKey", func(t *testing.T) { t.Parallel() - ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong*10) + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort) t.Cleanup(cancel) dv := coderdtest.DeploymentValues(t) client, owner := coderdenttest.New(t, &coderdenttest.Options{ @@ -153,18 +153,18 @@ func TestProvisionerKeyTags(t *testing.T) { }, }) - //nolint:gocritic // Not the purpose of this test - _, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ - Name: "key", + key, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ + Name: "my-test-key", Tags: map[string]string{"key1": "value1", "key2": "value2"}, }) require.NoError(t, err) - tags, err := client.FetchProvisionerTagsByKey(ctx, owner.OrganizationID, "key") + _, err = client.GetProvisionerKey(ctx, key.Key) require.NoError(t, err) - require.Equal(t, tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) + // require.Equal(t, tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) - _, err = client.FetchProvisionerTagsByKey(ctx, owner.OrganizationID, "invalid_key") - require.ErrorContains(t, err, "Resource not found") + erroneousPK, err := client.GetProvisionerKey(ctx, "abcdefghijklmnopqrstuvwxyz01234567890123456") + require.Empty(t, erroneousPK) + require.Error(t, err) }) } From 54437f2e4ebc7ae139ef583e8e4c3159b22e3da4 Mon Sep 17 00:00:00 2001 From: defelmnq Date: Mon, 18 Nov 2024 14:39:52 +0000 Subject: [PATCH 07/12] generate doc --- coderd/apidoc/docs.go | 75 ++++++++++---------- coderd/apidoc/swagger.json | 67 ++++++++---------- codersdk/provisionerdaemons.go | 2 +- docs/reference/api/enterprise.md | 83 ++++++++++++----------- enterprise/coderd/coderd.go | 2 +- enterprise/coderd/provisionerkeys.go | 10 +-- enterprise/coderd/provisionerkeys_test.go | 10 +-- 7 files changed, 121 insertions(+), 128 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 1a11de044a852..6410a8f9f7e4f 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -3126,47 +3126,6 @@ const docTemplate = `{ } } }, - "/organizations/{organization}/provisionerkeys/{provisionerkey}/tags": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get provisioner key tags by ID", - "operationId": "get-provisioner-key-tags-by-id", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Provisioner Key", - "name": "provisionerkey", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerKeyTags" - } - } - } - } - }, "/organizations/{organization}/settings/idpsync/groups": { "get": { "security": [ @@ -3635,6 +3594,40 @@ const docTemplate = `{ } } }, + "/provisionerkeys/{provisionerkey}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Fetch provisioner key details", + "operationId": "fetch-provisioner-key-details", + "parameters": [ + { + "type": "string", + "description": "Provisioner Key", + "name": "provisionerkey", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerKey" + } + } + } + } + }, "/regions": { "get": { "security": [ diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 348624883c3b9..6ae60ee74178d 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -2748,43 +2748,6 @@ } } }, - "/organizations/{organization}/provisionerkeys/{provisionerkey}/tags": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get provisioner key tags by ID", - "operationId": "get-provisioner-key-tags-by-id", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Provisioner Key", - "name": "provisionerkey", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerKeyTags" - } - } - } - } - }, "/organizations/{organization}/settings/idpsync/groups": { "get": { "security": [ @@ -3201,6 +3164,36 @@ } } }, + "/provisionerkeys/{provisionerkey}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Fetch provisioner key details", + "operationId": "fetch-provisioner-key-details", + "parameters": [ + { + "type": "string", + "description": "Provisioner Key", + "name": "provisionerkey", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerKey" + } + } + } + } + }, "/regions": { "get": { "security": [ diff --git a/codersdk/provisionerdaemons.go b/codersdk/provisionerdaemons.go index 011a59383a316..12b5ac97565a4 100644 --- a/codersdk/provisionerdaemons.go +++ b/codersdk/provisionerdaemons.go @@ -377,7 +377,7 @@ func (c *Client) GetProvisionerKey(ctx context.Context, pk string) (ProvisionerK }, ) if err != nil { - return ProvisionerKey{}, xerrors.Errorf("make request: %w", err) + return ProvisionerKey{}, xerrors.Errorf("request to fetch provisioner key failed: %w", err) } defer res.Body.Close() diff --git a/docs/reference/api/enterprise.md b/docs/reference/api/enterprise.md index 965955605394e..4f669aca05550 100644 --- a/docs/reference/api/enterprise.md +++ b/docs/reference/api/enterprise.md @@ -1777,45 +1777,6 @@ curl -X DELETE http://coder-server:8080/api/v2/organizations/{organization}/prov To perform this operation, you must be authenticated. [Learn more](authentication.md). -## Get provisioner key tags by ID - -### Code samples - -```shell -# Example request using curl -curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisionerkeys/{provisionerkey}/tags \ - -H 'Accept: application/json' \ - -H 'Coder-Session-Token: API_KEY' -``` - -`GET /organizations/{organization}/provisionerkeys/{provisionerkey}/tags` - -### Parameters - -| Name | In | Type | Required | Description | -| ---------------- | ---- | ------ | -------- | --------------- | -| `organization` | path | string | true | Organization ID | -| `provisionerkey` | path | string | true | Provisioner Key | - -### Example responses - -> 200 Response - -```json -{ - "property1": "string", - "property2": "string" -} -``` - -### Responses - -| Status | Meaning | Description | Schema | -| ------ | ------------------------------------------------------- | ----------- | -------------------------------------------------------------------- | -| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags) | - -To perform this operation, you must be authenticated. [Learn more](authentication.md). - ## Get group IdP Sync settings by organization ### Code samples @@ -2026,6 +1987,50 @@ curl -X PATCH http://coder-server:8080/api/v2/organizations/{organization}/setti To perform this operation, you must be authenticated. [Learn more](authentication.md). +## Fetch provisioner key details + +### Code samples + +```shell +# Example request using curl +curl -X GET http://coder-server:8080/api/v2/provisionerkeys/{provisionerkey} \ + -H 'Accept: application/json' \ + -H 'Coder-Session-Token: API_KEY' +``` + +`GET /provisionerkeys/{provisionerkey}` + +### Parameters + +| Name | In | Type | Required | Description | +| ---------------- | ---- | ------ | -------- | --------------- | +| `provisionerkey` | path | string | true | Provisioner Key | + +### Example responses + +> 200 Response + +```json +{ + "created_at": "2019-08-24T14:15:22Z", + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "string", + "organization": "452c1a86-a0af-475b-b03f-724878b0f387", + "tags": { + "property1": "string", + "property2": "string" + } +} +``` + +### Responses + +| Status | Meaning | Description | Schema | +| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------------------ | +| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.ProvisionerKey](schemas.md#codersdkprovisionerkey) | + +To perform this operation, you must be authenticated. [Learn more](authentication.md). + ## Get active replicas ### Code samples diff --git a/enterprise/coderd/coderd.go b/enterprise/coderd/coderd.go index 1b242f2b05137..dd18e6fd8c293 100644 --- a/enterprise/coderd/coderd.go +++ b/enterprise/coderd/coderd.go @@ -346,7 +346,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) { Optional: false, }), ) - r.Get("/{provisionerkey}", api.getProvisionerKey) + r.Get("/{provisionerkey}", api.fetchProvisionerKey) }) r.Route("/organizations/{organization}/provisionerkeys", func(r chi.Router) { r.Use( diff --git a/enterprise/coderd/provisionerkeys.go b/enterprise/coderd/provisionerkeys.go index 9f3e7dfac74cf..3ddefdc95ce3e 100644 --- a/enterprise/coderd/provisionerkeys.go +++ b/enterprise/coderd/provisionerkeys.go @@ -200,15 +200,15 @@ func (api *API) deleteProvisionerKey(rw http.ResponseWriter, r *http.Request) { httpapi.Write(ctx, rw, http.StatusNoContent, nil) } -// @Summary Get provisioner key details -// @ID get-provisioner-key -// @Security CoderProvisionerDaemonKey +// @Summary Fetch provisioner key details +// @ID fetch-provisioner-key-details +// @Security CoderSessionToken // @Produce json // @Tags Enterprise // @Param provisionerkey path string true "Provisioner Key" // @Success 200 {object} codersdk.ProvisionerKey -// @Router provisionerkeys/{provisionerkey} [get] -func (*API) getProvisionerKey(rw http.ResponseWriter, r *http.Request) { +// @Router /provisionerkeys/{provisionerkey} [get] +func (*API) fetchProvisionerKey(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() pk, ok := httpmw.ProvisionerKeyAuthOptional(r) diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 62852819fadcd..471ddd2c61a0d 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -139,8 +139,8 @@ func TestProvisionerKey(t *testing.T) { t.Run("GetKey", func(t *testing.T) { t.Parallel() - ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort) - t.Cleanup(cancel) + ctx := testutil.Context(t, testutil.WaitShort) + dv := coderdtest.DeploymentValues(t) client, owner := coderdenttest.New(t, &coderdenttest.Options{ Options: &coderdtest.Options{ @@ -153,15 +153,17 @@ func TestProvisionerKey(t *testing.T) { }, }) + // nolint:gocritic key, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ Name: "my-test-key", Tags: map[string]string{"key1": "value1", "key2": "value2"}, }) require.NoError(t, err) - _, err = client.GetProvisionerKey(ctx, key.Key) + fetchedKey, err := client.GetProvisionerKey(ctx, key.Key) require.NoError(t, err) - // require.Equal(t, tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) + require.Equal(t, fetchedKey.Name, "my-test-key") + require.Equal(t, fetchedKey.Tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) erroneousPK, err := client.GetProvisionerKey(ctx, "abcdefghijklmnopqrstuvwxyz01234567890123456") require.Empty(t, erroneousPK) From 8eeffb1351f79632b5e15147073965d71df666aa Mon Sep 17 00:00:00 2001 From: defelmnq Date: Mon, 18 Nov 2024 15:47:48 +0000 Subject: [PATCH 08/12] work on tests --- enterprise/coderd/provisionerkeys_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 471ddd2c61a0d..32321425129e5 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -148,7 +148,8 @@ func TestProvisionerKey(t *testing.T) { }, LicenseOptions: &coderdenttest.LicenseOptions{ Features: license.Features{ - codersdk.FeatureMultipleOrganizations: 1, + codersdk.FeatureMultipleOrganizations: 1, + codersdk.FeatureExternalProvisionerDaemons: 1, }, }, }) From 4a38977203ae16dae9b7e59b9b72cd7bef17249a Mon Sep 17 00:00:00 2001 From: defelmnq Date: Tue, 19 Nov 2024 16:08:44 +0000 Subject: [PATCH 09/12] improve testing strategy and errors handling --- enterprise/coderd/provisionerkeys.go | 4 +- enterprise/coderd/provisionerkeys_test.go | 84 ++++++++++++++--------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/enterprise/coderd/provisionerkeys.go b/enterprise/coderd/provisionerkeys.go index 65ca14979dd56..a14e2c965c919 100644 --- a/enterprise/coderd/provisionerkeys.go +++ b/enterprise/coderd/provisionerkeys.go @@ -214,7 +214,9 @@ func (*API) fetchProvisionerKey(rw http.ResponseWriter, r *http.Request) { pk, ok := httpmw.ProvisionerKeyAuthOptional(r) // extra check but this one should never happen as it is covered by the auth middleware if !ok { - httpapi.Forbidden(rw) + httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{ + Message: fmt.Sprintf("unable to auth: please provide the %s header", codersdk.ProvisionerDaemonKey), + }) return } diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 2ef7b37e8a98b..34764d27f291f 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -135,40 +135,62 @@ func TestProvisionerKeys(t *testing.T) { require.ErrorContains(t, err, "reserved") } -func TestProvisionerKey(t *testing.T) { +func TestGetProvisionerKey(t *testing.T) { t.Parallel() - t.Run("GetKey", func(t *testing.T) { - t.Parallel() - ctx := testutil.Context(t, testutil.WaitShort) + tests := []struct { + name string + useFakeKey bool + fakeKey string + success bool + expectedErr string + }{ + { + name: "ok", + useFakeKey: false, + success: true, + expectedErr: "", + }, + } - dv := coderdtest.DeploymentValues(t) - client, owner := coderdenttest.New(t, &coderdenttest.Options{ - Options: &coderdtest.Options{ - DeploymentValues: dv, - }, - LicenseOptions: &coderdenttest.LicenseOptions{ - Features: license.Features{ - codersdk.FeatureMultipleOrganizations: 1, - codersdk.FeatureExternalProvisionerDaemons: 1, - }, - }, - }) + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() - // nolint:gocritic - key, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ - Name: "my-test-key", - Tags: map[string]string{"key1": "value1", "key2": "value2"}, + ctx := testutil.Context(t, testutil.WaitShort) + dv := coderdtest.DeploymentValues(t) + client, owner := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + DeploymentValues: dv, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureMultipleOrganizations: 1, + codersdk.FeatureExternalProvisionerDaemons: 1, + }, + }, + }) + + key, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ + Name: "my-test-key", + Tags: map[string]string{"key1": "value1", "key2": "value2"}, + }) + require.NoError(t, err) + + pk := key.Key + if tt.useFakeKey { + pk = tt.fakeKey + } + + fetchedKey, err := client.GetProvisionerKey(ctx, pk) + if !tt.success { + require.ErrorContains(t, err, tt.expectedErr) + } else { + require.NoError(t, err) + require.Equal(t, fetchedKey.Name, "my-test-key") + require.Equal(t, fetchedKey.Tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) + } }) - require.NoError(t, err) - - fetchedKey, err := client.GetProvisionerKey(ctx, key.Key) - require.NoError(t, err) - require.Equal(t, fetchedKey.Name, "my-test-key") - require.Equal(t, fetchedKey.Tags, codersdk.ProvisionerKeyTags{"key1": "value1", "key2": "value2"}) - - erroneousPK, err := client.GetProvisionerKey(ctx, "abcdefghijklmnopqrstuvwxyz01234567890123456") - require.Empty(t, erroneousPK) - require.Error(t, err) - }) + } } From c89bcd8927a114517a16d235d4bad22f40c48a0e Mon Sep 17 00:00:00 2001 From: defelmnq Date: Wed, 20 Nov 2024 09:22:30 +0000 Subject: [PATCH 10/12] add missing tests --- enterprise/coderd/provisionerkeys_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 34764d27f291f..f44aa10a2f474 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -151,6 +151,20 @@ func TestGetProvisionerKey(t *testing.T) { success: true, expectedErr: "", }, + { + name: "using unknown key", + useFakeKey: true, + fakeKey: "unknownKey", + success: false, + expectedErr: "provisioner daemon key invalid", + }, + { + name: "no key provided", + useFakeKey: true, + fakeKey: "", + success: false, + expectedErr: "provisioner daemon key required", + }, } for _, tt := range tests { From 0af9e8e572e6a2cd53dbee7f31945ea2837e23c4 Mon Sep 17 00:00:00 2001 From: defelmnq Date: Wed, 20 Nov 2024 14:12:08 +0000 Subject: [PATCH 11/12] work on tests --- enterprise/coderd/provisionerkeys_test.go | 61 ++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index f44aa10a2f474..576782e434445 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -147,7 +147,6 @@ func TestGetProvisionerKey(t *testing.T) { }{ { name: "ok", - useFakeKey: false, success: true, expectedErr: "", }, @@ -186,6 +185,7 @@ func TestGetProvisionerKey(t *testing.T) { }, }) + //nolint:gocritic // ignore This client is operating as the owner user, which has unrestricted permissions key, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ Name: "my-test-key", Tags: map[string]string{"key1": "value1", "key2": "value2"}, @@ -207,4 +207,63 @@ func TestGetProvisionerKey(t *testing.T) { } }) } + + t.Run("TestPSK", func(t *testing.T) { + t.Parallel() + + ctx := testutil.Context(t, testutil.WaitShort) + dv := coderdtest.DeploymentValues(t) + client, owner := coderdenttest.New(t, &coderdenttest.Options{ + ProvisionerDaemonPSK: "psk-testing-purpose", + Options: &coderdtest.Options{ + DeploymentValues: dv, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureMultipleOrganizations: 1, + codersdk.FeatureExternalProvisionerDaemons: 1, + }, + }, + }) + + //nolint:gocritic // ignore This client is operating as the owner user, which has unrestricted permissions + _, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ + Name: "my-test-key", + Tags: map[string]string{"key1": "value1", "key2": "value2"}, + }) + require.NoError(t, err) + + fetchedKey, err := client.GetProvisionerKey(ctx, "psk-testing-purpose") + require.Error(t, err) + require.Empty(t, fetchedKey) + }) + + t.Run("TestSessionToken", func(t *testing.T) { + t.Parallel() + + ctx := testutil.Context(t, testutil.WaitShort) + dv := coderdtest.DeploymentValues(t) + client, owner := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + DeploymentValues: dv, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureMultipleOrganizations: 1, + codersdk.FeatureExternalProvisionerDaemons: 1, + }, + }, + }) + + //nolint:gocritic // ignore This client is operating as the owner user, which has unrestricted permissions + _, err := client.CreateProvisionerKey(ctx, owner.OrganizationID, codersdk.CreateProvisionerKeyRequest{ + Name: "my-test-key", + Tags: map[string]string{"key1": "value1", "key2": "value2"}, + }) + require.NoError(t, err) + + fetchedKey, err := client.GetProvisionerKey(ctx, client.SessionToken()) + require.Error(t, err) + require.Empty(t, fetchedKey) + }) } From 4680484bde4ec717ab85e7c121aa93e44eb81db1 Mon Sep 17 00:00:00 2001 From: defelmnq Date: Wed, 20 Nov 2024 15:56:03 +0000 Subject: [PATCH 12/12] improved test logic --- enterprise/coderd/provisionerkeys_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/enterprise/coderd/provisionerkeys_test.go b/enterprise/coderd/provisionerkeys_test.go index 576782e434445..e3f5839bf8b02 100644 --- a/enterprise/coderd/provisionerkeys_test.go +++ b/enterprise/coderd/provisionerkeys_test.go @@ -210,11 +210,11 @@ func TestGetProvisionerKey(t *testing.T) { t.Run("TestPSK", func(t *testing.T) { t.Parallel() - + const testPSK = "psk-testing-purpose" ctx := testutil.Context(t, testutil.WaitShort) dv := coderdtest.DeploymentValues(t) client, owner := coderdenttest.New(t, &coderdenttest.Options{ - ProvisionerDaemonPSK: "psk-testing-purpose", + ProvisionerDaemonPSK: testPSK, Options: &coderdtest.Options{ DeploymentValues: dv, }, @@ -233,8 +233,8 @@ func TestGetProvisionerKey(t *testing.T) { }) require.NoError(t, err) - fetchedKey, err := client.GetProvisionerKey(ctx, "psk-testing-purpose") - require.Error(t, err) + fetchedKey, err := client.GetProvisionerKey(ctx, testPSK) + require.ErrorContains(t, err, "provisioner daemon key invalid") require.Empty(t, fetchedKey) }) @@ -263,7 +263,7 @@ func TestGetProvisionerKey(t *testing.T) { require.NoError(t, err) fetchedKey, err := client.GetProvisionerKey(ctx, client.SessionToken()) - require.Error(t, err) + require.ErrorContains(t, err, "provisioner daemon key invalid") require.Empty(t, fetchedKey) }) } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy