Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add unit test for moons
  • Loading branch information
Emyrk committed Mar 31, 2023
commit a593520f6a26d4e5ebc1b8c43a18576eb89162c0
2 changes: 1 addition & 1 deletion coderd/database/dbauthz/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -1648,7 +1648,7 @@ func (q *querier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspaceApp
}

func (q *querier) GetWorkspaceProxies(ctx context.Context, organizationID uuid.UUID) ([]database.WorkspaceProxy, error) {
return fetchWithPostFilter(q.auth, q.GetWorkspaceProxies)(ctx, organizationID)
return fetchWithPostFilter(q.auth, q.db.GetWorkspaceProxies)(ctx, organizationID)
}

func (q *querier) GetWorkspaceProxyByID(ctx context.Context, id uuid.UUID) (database.WorkspaceProxy, error) {
Expand Down
2 changes: 2 additions & 0 deletions codersdk/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (
FeatureExternalProvisionerDaemons FeatureName = "external_provisioner_daemons"
FeatureAppearance FeatureName = "appearance"
FeatureAdvancedTemplateScheduling FeatureName = "advanced_template_scheduling"
FeatureWorkspaceProxy FeatureName = "workspace_proxy"
)

// FeatureNames must be kept in-sync with the Feature enum above.
Expand All @@ -59,6 +60,7 @@ var FeatureNames = []FeatureName{
FeatureExternalProvisionerDaemons,
FeatureAppearance,
FeatureAdvancedTemplateScheduling,
FeatureWorkspaceProxy,
}

// Humanize returns the feature name in a human-readable format.
Expand Down
41 changes: 41 additions & 0 deletions codersdk/workspaceproxy.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package codersdk

import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"

"golang.org/x/xerrors"

"github.com/google/uuid"
)

Expand All @@ -26,3 +32,38 @@ type WorkspaceProxy struct {
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Deleted bool `db:"deleted" json:"deleted"`
}

func (c *Client) CreateWorkspaceProxy(ctx context.Context, orgID uuid.UUID, req CreateWorkspaceProxyRequest) (WorkspaceProxy, error) {
res, err := c.Request(ctx, http.MethodPost,
fmt.Sprintf("/api/v2/organizations/%s/workspaceproxies", orgID.String()),
req,
)
if err != nil {
return WorkspaceProxy{}, xerrors.Errorf("make request: %w", err)
}
defer res.Body.Close()

if res.StatusCode != http.StatusCreated {
return WorkspaceProxy{}, ReadBodyAsError(res)
}
var resp WorkspaceProxy
return resp, json.NewDecoder(res.Body).Decode(&resp)
}

func (c *Client) WorkspaceProxiesByOrganization(ctx context.Context, orgID uuid.UUID) ([]WorkspaceProxy, error) {
res, err := c.Request(ctx, http.MethodGet,
fmt.Sprintf("/api/v2/organizations/%s/workspaceproxies", orgID.String()),
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 proxies []WorkspaceProxy
return proxies, json.NewDecoder(res.Body).Decode(&proxies)
}
3 changes: 2 additions & 1 deletion enterprise/coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func New(ctx context.Context, options *Options) (*API, error) {
r.Get("/", api.licenses)
r.Delete("/{id}", api.deleteLicense)
})
r.Route("/organizations/{organization}/workspaceproxys", func(r chi.Router) {
r.Route("/organizations/{organization}/workspaceproxies", func(r chi.Router) {
r.Use(
apiKeyMiddleware,
api.moonsEnabledMW,
Expand Down Expand Up @@ -271,6 +271,7 @@ func (api *API) updateEntitlements(ctx context.Context) error {
codersdk.FeatureTemplateRBAC: api.RBAC,
codersdk.FeatureExternalProvisionerDaemons: true,
codersdk.FeatureAdvancedTemplateScheduling: true,
codersdk.FeatureWorkspaceProxy: true,
})
if err != nil {
return err
Expand Down
11 changes: 11 additions & 0 deletions enterprise/coderd/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,21 @@ func (api *API) templateRBACEnabledMW(next http.Handler) http.Handler {

func (api *API) moonsEnabledMW(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
// The experiment must be enabled.
if !api.AGPL.Experiments.Enabled(codersdk.ExperimentMoons) {
httpapi.RouteNotFound(rw)
return
}

// Entitlement must be enabled.
api.entitlementsMu.RLock()
proxy := api.entitlements.Features[codersdk.FeatureWorkspaceProxy].Enabled
api.entitlementsMu.RUnlock()
if !proxy {
httpapi.RouteNotFound(rw)
return
}

next.ServeHTTP(rw, r)
})
}
6 changes: 2 additions & 4 deletions enterprise/coderd/workspaceproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
// @Param request body codersdk.CreateWorkspaceProxyRequest true "Create workspace proxy request"
// @Param organization path string true "Organization ID"
// @Success 201 {object} codersdk.WorkspaceProxy
// @Router /organizations/{organization}/workspaceproxys [post]
// @Router /organizations/{organization}/workspaceproxies [post]
func (api *API) postWorkspaceProxyByOrganization(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
Expand Down Expand Up @@ -77,7 +77,7 @@ func (api *API) postWorkspaceProxyByOrganization(rw http.ResponseWriter, r *http
// @Tags Enterprise
// @Param organization path string true "Organization ID" format(uuid)
// @Success 200 {array} codersdk.WorkspaceProxy
// @Router /organizations/{organization}/workspaceproxys [get]
// @Router /organizations/{organization}/workspaceproxies [get]
func (api *API) workspaceProxiesByOrganization(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
Expand All @@ -93,8 +93,6 @@ func (api *API) workspaceProxiesByOrganization(rw http.ResponseWriter, r *http.R
httpapi.Write(ctx, rw, http.StatusOK, convertProxies(proxies))
}



func convertProxies(p []database.WorkspaceProxy) []codersdk.WorkspaceProxy {
resp := make([]codersdk.WorkspaceProxy, 0, len(p))
for _, proxy := range p {
Expand Down
50 changes: 50 additions & 0 deletions enterprise/coderd/workspaceproxy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package coderd_test

import (
"testing"

"github.com/moby/moby/pkg/namesgenerator"

"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
"github.com/stretchr/testify/require"
)

func TestWorkspaceProxyCRUD(t *testing.T) {
t.Parallel()

t.Run("create", func(t *testing.T) {
dv := coderdtest.DeploymentValues(t)
dv.Experiments = []string{
string(codersdk.ExperimentMoons),
"*",
}
client := coderdenttest.New(t, &coderdenttest.Options{
Options: &coderdtest.Options{
DeploymentValues: dv,
},
})
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureWorkspaceProxy: 1,
},
})
ctx := testutil.Context(t, testutil.WaitLong)
proxy, err := client.CreateWorkspaceProxy(ctx, user.OrganizationID, codersdk.CreateWorkspaceProxyRequest{
Name: namesgenerator.GetRandomName(1),
Icon: "/emojis/flag.png",
URL: "https://" + namesgenerator.GetRandomName(1) + ".com",
WildcardURL: "https://*." + namesgenerator.GetRandomName(1) + ".com",
})
require.NoError(t, err)

proxies, err := client.WorkspaceProxiesByOrganization(ctx, user.OrganizationID)
require.NoError(t, err)
require.Len(t, proxies, 1)
require.Equal(t, proxy, proxies[0])
})
}