From 85499af2e2aa4cca43f0321aae318fa5b616c706 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 21 Jun 2024 11:29:31 -0500 Subject: [PATCH 1/2] chore: add coderdtest helpers --- coderd/coderdtest/coderdtest.go | 44 ++++++++++++++++++ enterprise/cli/templatecreate_test.go | 66 +++++++++++++++++++++++++++ enterprise/coderd/templates_test.go | 50 ++++++++++++++++++++ 3 files changed, 160 insertions(+) diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index 49388aa3537a5..d4e473a17a610 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -600,6 +600,18 @@ func NewTaggedProvisionerDaemon(t testing.TB, coderAPI *coderd.API, name string, } func NewExternalProvisionerDaemon(t testing.TB, client *codersdk.Client, org uuid.UUID, tags map[string]string) io.Closer { + t.Helper() + + // Without this check, the provisioner will silently fail. + entitlements, err := client.Entitlements(context.Background()) + if err == nil { + feature := entitlements.Features[codersdk.FeatureExternalProvisionerDaemons] + if !feature.Enabled || feature.Entitlement != codersdk.EntitlementEntitled { + require.NoError(t, xerrors.Errorf("external provisioner daemons require an entitled license")) + return nil + } + } + echoClient, echoServer := drpc.MemTransportPipe() ctx, cancelFunc := context.WithCancel(context.Background()) serveDone := make(chan struct{}) @@ -638,6 +650,7 @@ func NewExternalProvisionerDaemon(t testing.TB, client *codersdk.Client, org uui t.Cleanup(func() { _ = closer.Close() }) + return closer } @@ -790,6 +803,37 @@ func createAnotherUserRetry(t testing.TB, client *codersdk.Client, organizationI return other, user } +type CreateOrganizationOptions struct { + // IncludeProvisionerDaemon will spin up an external provisioner for the organization. + // This requires enterprise and the feature 'codersdk.FeatureExternalProvisionerDaemons' + IncludeProvisionerDaemon bool +} + +func CreateOrganization(t *testing.T, client *codersdk.Client, opts CreateOrganizationOptions, mutators ...func(*codersdk.CreateOrganizationRequest)) codersdk.Organization { + ctx := testutil.Context(t, testutil.WaitMedium) + req := codersdk.CreateOrganizationRequest{ + Name: strings.ReplaceAll(strings.ToLower(namesgenerator.GetRandomName(0)), "_", "-"), + DisplayName: namesgenerator.GetRandomName(1), + Description: namesgenerator.GetRandomName(1), + Icon: "", + } + for _, mutator := range mutators { + mutator(&req) + } + + org, err := client.CreateOrganization(ctx, req) + require.NoError(t, err) + + if opts.IncludeProvisionerDaemon { + closer := NewExternalProvisionerDaemon(t, client, org.ID, map[string]string{}) + t.Cleanup(func() { + _ = closer.Close() + }) + } + + return org +} + // CreateTemplateVersion creates a template import provisioner job // with the responses provided. It uses the "echo" provisioner for compatibility // with testing. diff --git a/enterprise/cli/templatecreate_test.go b/enterprise/cli/templatecreate_test.go index 987cac0b93058..ddbbabe1ce769 100644 --- a/enterprise/cli/templatecreate_test.go +++ b/enterprise/cli/templatecreate_test.go @@ -134,4 +134,70 @@ func TestTemplateCreate(t *testing.T) { require.Error(t, err) require.Contains(t, err.Error(), "your license is not entitled to use enterprise access control, so you cannot set --require-active-version") }) + + // Create a template in a second organization via custom role + t.Run("SecondOrganization", func(t *testing.T) { + t.Parallel() + + dv := coderdtest.DeploymentValues(t) + dv.Experiments = []string{string(codersdk.ExperimentCustomRoles)} + ownerClient, _ := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + DeploymentValues: dv, + // This only affects the first org. + IncludeProvisionerDaemon: false, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureAccessControl: 1, + codersdk.FeatureCustomRoles: 1, + codersdk.FeatureExternalProvisionerDaemons: 1, + }, + }, + }) + + // Create the second organization + secondOrg := coderdtest.CreateOrganization(t, ownerClient, coderdtest.CreateOrganizationOptions{ + IncludeProvisionerDaemon: true, + }) + + ctx := testutil.Context(t, testutil.WaitMedium) + + orgTemplateAdminRole, err := ownerClient.PatchOrganizationRole(ctx, secondOrg.ID, codersdk.Role{ + Name: "org-template-admin", + OrganizationID: secondOrg.ID.String(), + OrganizationPermissions: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{ + codersdk.ResourceTemplate: codersdk.RBACResourceActions[codersdk.ResourceTemplate], + }), + }) + require.NoError(t, err, "create admin role") + + orgTemplateAdmin, _ := coderdtest.CreateAnotherUser(t, ownerClient, secondOrg.ID, rbac.RoleIdentifier{ + Name: orgTemplateAdminRole.Name, + OrganizationID: secondOrg.ID, + }) + + source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionApply: echo.ApplyComplete, + }) + + const templateName = "new-template" + inv, conf := newCLI(t, "templates", + "push", templateName, + "--directory", source, + "--test.provisioner", string(database.ProvisionerTypeEcho), + "-y", + ) + + clitest.SetupConfig(t, orgTemplateAdmin, conf) + + err = inv.Run() + require.NoError(t, err) + + ctx = testutil.Context(t, testutil.WaitMedium) + template, err := orgTemplateAdmin.TemplateByName(ctx, secondOrg.ID, templateName) + require.NoError(t, err) + require.Equal(t, template.OrganizationID, secondOrg.ID) + }) } diff --git a/enterprise/coderd/templates_test.go b/enterprise/coderd/templates_test.go index 7440ee743dca2..2eaddabe5442a 100644 --- a/enterprise/coderd/templates_test.go +++ b/enterprise/coderd/templates_test.go @@ -717,6 +717,56 @@ func TestTemplates(t *testing.T) { _, err = owner.Template(ctx, template.ID) require.NoError(t, err) }) + + // Create a template in a second organization via custom role + t.Run("SecondOrganization", func(t *testing.T) { + t.Parallel() + + dv := coderdtest.DeploymentValues(t) + dv.Experiments = []string{string(codersdk.ExperimentCustomRoles)} + ownerClient, _ := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + DeploymentValues: dv, + IncludeProvisionerDaemon: false, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureAccessControl: 1, + codersdk.FeatureCustomRoles: 1, + codersdk.FeatureExternalProvisionerDaemons: 1, + }, + }, + }) + + ctx := testutil.Context(t, testutil.WaitMedium) + secondOrg := coderdtest.CreateOrganization(t, ownerClient, coderdtest.CreateOrganizationOptions{ + IncludeProvisionerDaemon: true, + }) + + orgTemplateAdminRole, err := ownerClient.PatchOrganizationRole(ctx, secondOrg.ID, codersdk.Role{ + Name: "org-template-admin", + OrganizationID: secondOrg.ID.String(), + OrganizationPermissions: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{ + codersdk.ResourceTemplate: codersdk.RBACResourceActions[codersdk.ResourceTemplate], + }), + }) + require.NoError(t, err, "create admin role") + + orgTemplateAdmin, _ := coderdtest.CreateAnotherUser(t, ownerClient, secondOrg.ID, rbac.RoleIdentifier{ + Name: orgTemplateAdminRole.Name, + OrganizationID: secondOrg.ID, + }) + + version := coderdtest.CreateTemplateVersion(t, orgTemplateAdmin, secondOrg.ID, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionApply: echo.ApplyComplete, + ProvisionPlan: echo.PlanComplete, + }) + coderdtest.AwaitTemplateVersionJobCompleted(t, orgTemplateAdmin, version.ID) + + template := coderdtest.CreateTemplate(t, orgTemplateAdmin, secondOrg.ID, version.ID) + require.Equal(t, template.OrganizationID, secondOrg.ID) + }) } func TestTemplateACL(t *testing.T) { From 956b5a297b09a2be9aa79c6c753d93ea41c41972 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 21 Jun 2024 12:06:21 -0500 Subject: [PATCH 2/2] linting --- enterprise/cli/templatecreate_test.go | 1 + enterprise/coderd/templates_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/enterprise/cli/templatecreate_test.go b/enterprise/cli/templatecreate_test.go index ddbbabe1ce769..3f089a62622a6 100644 --- a/enterprise/cli/templatecreate_test.go +++ b/enterprise/cli/templatecreate_test.go @@ -163,6 +163,7 @@ func TestTemplateCreate(t *testing.T) { ctx := testutil.Context(t, testutil.WaitMedium) + //nolint:gocritic // owner required to make custom roles orgTemplateAdminRole, err := ownerClient.PatchOrganizationRole(ctx, secondOrg.ID, codersdk.Role{ Name: "org-template-admin", OrganizationID: secondOrg.ID.String(), diff --git a/enterprise/coderd/templates_test.go b/enterprise/coderd/templates_test.go index 2eaddabe5442a..80000f2eb22b4 100644 --- a/enterprise/coderd/templates_test.go +++ b/enterprise/coderd/templates_test.go @@ -743,6 +743,7 @@ func TestTemplates(t *testing.T) { IncludeProvisionerDaemon: true, }) + //nolint:gocritic // owner required to make custom roles orgTemplateAdminRole, err := ownerClient.PatchOrganizationRole(ctx, secondOrg.ID, codersdk.Role{ Name: "org-template-admin", OrganizationID: secondOrg.ID.String(), 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