Skip to content

Commit 50124fe

Browse files
authored
feat: remove org flag requirement for provisioners (#14722)
1 parent 96e9a4f commit 50124fe

File tree

4 files changed

+93
-157
lines changed

4 files changed

+93
-157
lines changed

enterprise/cli/provisionerdaemonstart.go

+30-44
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/coder/coder/v2/cli/cliui"
2525
"github.com/coder/coder/v2/cli/cliutil"
2626
"github.com/coder/coder/v2/coderd/database"
27-
"github.com/coder/coder/v2/coderd/provisionerkey"
2827
"github.com/coder/coder/v2/codersdk"
2928
"github.com/coder/coder/v2/codersdk/drpc"
3029
"github.com/coder/coder/v2/provisioner/terraform"
@@ -73,32 +72,30 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
7372
interruptCtx, interruptCancel := inv.SignalNotifyContext(ctx, agpl.InterruptSignals...)
7473
defer interruptCancel()
7574

76-
// This can fail to get the current organization
77-
// if the client is not authenticated as a user,
78-
// like when only PSK is provided.
79-
// This will be cleaner once PSK is replaced
80-
// with org scoped authentication tokens.
81-
org, err := orgContext.Selected(inv, client)
82-
if err != nil {
83-
var cErr *codersdk.Error
84-
if !errors.As(err, &cErr) || cErr.StatusCode() != http.StatusUnauthorized {
85-
return xerrors.Errorf("current organization: %w", err)
86-
}
75+
orgID := uuid.Nil
76+
if preSharedKey == "" && provisionerKey == "" {
77+
// We can only select an organization if using user auth
78+
org, err := orgContext.Selected(inv, client)
79+
if err != nil {
80+
var cErr *codersdk.Error
81+
if !errors.As(err, &cErr) || cErr.StatusCode() != http.StatusUnauthorized {
82+
return xerrors.Errorf("current organization: %w", err)
83+
}
8784

88-
if preSharedKey == "" && provisionerKey == "" {
8985
return xerrors.New("must provide a pre-shared key or provisioner key when not authenticated as a user")
9086
}
9187

92-
org = codersdk.Organization{MinimalOrganization: codersdk.MinimalOrganization{ID: uuid.Nil}}
93-
if orgContext.FlagSelect != "" {
94-
// If we are using PSK, we can't fetch the organization
95-
// to validate org name so we need the user to provide
96-
// a valid organization ID.
97-
orgID, err := uuid.Parse(orgContext.FlagSelect)
98-
if err != nil {
99-
return xerrors.New("must provide an org ID when not authenticated as a user and organization is specified")
100-
}
101-
org = codersdk.Organization{MinimalOrganization: codersdk.MinimalOrganization{ID: orgID}}
88+
orgID = org.ID
89+
} else if orgContext.FlagSelect != "" {
90+
return xerrors.New("cannot provide --org value with --psk or --key flags")
91+
}
92+
93+
if provisionerKey != "" {
94+
if preSharedKey != "" {
95+
return xerrors.New("cannot provide both provisioner key --key and pre-shared key --psk")
96+
}
97+
if len(rawTags) > 0 {
98+
return xerrors.New("cannot provide tags when using provisioner key")
10299
}
103100
}
104101

@@ -115,19 +112,6 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
115112
return err
116113
}
117114

118-
if provisionerKey != "" {
119-
if preSharedKey != "" {
120-
return xerrors.New("cannot provide both provisioner key --key and pre-shared key --psk")
121-
}
122-
if len(rawTags) > 0 {
123-
return xerrors.New("cannot provide tags when using provisioner key")
124-
}
125-
err = provisionerkey.Validate(provisionerKey)
126-
if err != nil {
127-
return xerrors.Errorf("validate provisioner key: %w", err)
128-
}
129-
}
130-
131115
logOpts := []clilog.Option{
132116
clilog.WithFilter(logFilter...),
133117
clilog.WithHuman(logHuman),
@@ -232,7 +216,7 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
232216
},
233217
Tags: tags,
234218
PreSharedKey: preSharedKey,
235-
Organization: org.ID,
219+
Organization: orgID,
236220
ProvisionerKey: provisionerKey,
237221
})
238222
}, &provisionerd.Options{
@@ -281,6 +265,13 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
281265
},
282266
}
283267

268+
keyOption := serpent.Option{
269+
Flag: "key",
270+
Env: "CODER_PROVISIONER_DAEMON_KEY",
271+
Description: "Provisioner key to authenticate with Coder server.",
272+
Value: serpent.StringOf(&provisionerKey),
273+
Hidden: true,
274+
}
284275
cmd.Options = serpent.OptionSet{
285276
{
286277
Flag: "cache-dir",
@@ -316,14 +307,9 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
316307
Env: "CODER_PROVISIONER_DAEMON_PSK",
317308
Description: "Pre-shared key to authenticate with Coder server.",
318309
Value: serpent.StringOf(&preSharedKey),
310+
UseInstead: []serpent.Option{keyOption},
319311
},
320-
{
321-
Flag: "key",
322-
Env: "CODER_PROVISIONER_DAEMON_KEY",
323-
Description: "Provisioner key to authenticate with Coder server.",
324-
Value: serpent.StringOf(&provisionerKey),
325-
Hidden: true,
326-
},
312+
keyOption,
327313
{
328314
Flag: "name",
329315
Env: "CODER_PROVISIONER_DAEMON_NAME",

enterprise/cli/provisionerdaemonstart_test.go

+2-68
Original file line numberDiff line numberDiff line change
@@ -68,46 +68,6 @@ func TestProvisionerDaemon_PSK(t *testing.T) {
6868
require.Equal(t, proto.CurrentVersion.String(), daemons[0].APIVersion)
6969
})
7070

71-
t.Run("AnotherOrg", func(t *testing.T) {
72-
t.Parallel()
73-
dv := coderdtest.DeploymentValues(t)
74-
dv.Experiments = []string{string(codersdk.ExperimentMultiOrganization)}
75-
client, _ := coderdenttest.New(t, &coderdenttest.Options{
76-
Options: &coderdtest.Options{
77-
DeploymentValues: dv,
78-
},
79-
ProvisionerDaemonPSK: "provisionersftw",
80-
LicenseOptions: &coderdenttest.LicenseOptions{
81-
Features: license.Features{
82-
codersdk.FeatureExternalProvisionerDaemons: 1,
83-
codersdk.FeatureMultipleOrganizations: 1,
84-
},
85-
},
86-
})
87-
anotherOrg := coderdenttest.CreateOrganization(t, client, coderdenttest.CreateOrganizationOptions{})
88-
inv, conf := newCLI(t, "provisionerd", "start", "--psk=provisionersftw", "--name", "org-daemon", "--org", anotherOrg.ID.String())
89-
err := conf.URL().Write(client.URL.String())
90-
require.NoError(t, err)
91-
pty := ptytest.New(t).Attach(inv)
92-
ctx, cancel := context.WithTimeout(inv.Context(), testutil.WaitLong)
93-
defer cancel()
94-
clitest.Start(t, inv)
95-
pty.ExpectMatchContext(ctx, "starting provisioner daemon")
96-
97-
var daemons []codersdk.ProvisionerDaemon
98-
require.Eventually(t, func() bool {
99-
daemons, err = client.OrganizationProvisionerDaemons(ctx, anotherOrg.ID)
100-
if err != nil {
101-
return false
102-
}
103-
return len(daemons) == 1
104-
}, testutil.WaitShort, testutil.IntervalSlow)
105-
assert.Equal(t, "org-daemon", daemons[0].Name)
106-
assert.Equal(t, provisionersdk.ScopeOrganization, daemons[0].Tags[provisionersdk.TagScope])
107-
assert.Equal(t, buildinfo.Version(), daemons[0].Version)
108-
assert.Equal(t, proto.CurrentVersion.String(), daemons[0].APIVersion)
109-
})
110-
11171
t.Run("AnotherOrgByNameWithUser", func(t *testing.T) {
11272
t.Parallel()
11373
dv := coderdtest.DeploymentValues(t)
@@ -126,7 +86,7 @@ func TestProvisionerDaemon_PSK(t *testing.T) {
12686
})
12787
anotherOrg := coderdenttest.CreateOrganization(t, client, coderdenttest.CreateOrganizationOptions{})
12888
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, anotherOrg.ID, rbac.RoleTemplateAdmin())
129-
inv, conf := newCLI(t, "provisionerd", "start", "--psk=provisionersftw", "--name", "org-daemon", "--org", anotherOrg.Name)
89+
inv, conf := newCLI(t, "provisionerd", "start", "--name", "org-daemon", "--org", anotherOrg.Name)
13090
clitest.SetupConfig(t, anotherClient, conf)
13191
pty := ptytest.New(t).Attach(inv)
13292
ctx, cancel := context.WithTimeout(inv.Context(), testutil.WaitLong)
@@ -135,32 +95,6 @@ func TestProvisionerDaemon_PSK(t *testing.T) {
13595
pty.ExpectMatchContext(ctx, "starting provisioner daemon")
13696
})
13797

138-
t.Run("AnotherOrgByNameNoUser", func(t *testing.T) {
139-
t.Parallel()
140-
dv := coderdtest.DeploymentValues(t)
141-
dv.Experiments = []string{string(codersdk.ExperimentMultiOrganization)}
142-
client, _ := coderdenttest.New(t, &coderdenttest.Options{
143-
Options: &coderdtest.Options{
144-
DeploymentValues: dv,
145-
},
146-
ProvisionerDaemonPSK: "provisionersftw",
147-
LicenseOptions: &coderdenttest.LicenseOptions{
148-
Features: license.Features{
149-
codersdk.FeatureExternalProvisionerDaemons: 1,
150-
codersdk.FeatureMultipleOrganizations: 1,
151-
},
152-
},
153-
})
154-
anotherOrg := coderdenttest.CreateOrganization(t, client, coderdenttest.CreateOrganizationOptions{})
155-
inv, conf := newCLI(t, "provisionerd", "start", "--psk=provisionersftw", "--name", "org-daemon", "--org", anotherOrg.Name)
156-
err := conf.URL().Write(client.URL.String())
157-
require.NoError(t, err)
158-
ctx, cancel := context.WithTimeout(inv.Context(), testutil.WaitLong)
159-
defer cancel()
160-
err = inv.WithContext(ctx).Run()
161-
require.ErrorContains(t, err, "must provide an org ID when not authenticated as a user and organization is specified")
162-
})
163-
16498
t.Run("NoUserNoPSK", func(t *testing.T) {
16599
t.Parallel()
166100
client, _ := coderdenttest.New(t, &coderdenttest.Options{
@@ -467,7 +401,7 @@ func TestProvisionerDaemon_ProvisionerKey(t *testing.T) {
467401
Name: "dont-TEST-me",
468402
})
469403
require.NoError(t, err)
470-
inv, conf := newCLI(t, "provisionerd", "start", "--org", anotherOrg.ID.String(), "--key", res.Key, "--name=matt-daemon")
404+
inv, conf := newCLI(t, "provisionerd", "start", "--key", res.Key, "--name=matt-daemon")
471405
err = conf.URL().Write(client.URL.String())
472406
require.NoError(t, err)
473407
pty := ptytest.New(t).Attach(inv)

enterprise/cli/testdata/coder_provisionerd_start_--help.golden

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ OPTIONS:
4343

4444
--psk string, $CODER_PROVISIONER_DAEMON_PSK
4545
Pre-shared key to authenticate with Coder server.
46+
DEPRECATED: Use --key instead.
4647

4748
-t, --tag string-array, $CODER_PROVISIONERD_TAGS
4849
Tags to filter provisioner jobs by.

0 commit comments

Comments
 (0)