feat(coderd): wire through strict tag policy

This commit is contained in:
Cian Johnston 2024-02-21 21:12:59 +00:00
parent 14fd776f46
commit a327f61219
11 changed files with 116 additions and 6 deletions

View File

@ -586,7 +586,8 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
HostnamePrefix: vals.SSHConfig.DeploymentName.String(),
SSHConfigOptions: configSSHOptions,
},
AllowWorkspaceRenames: vals.AllowWorkspaceRenames.Value(),
AllowWorkspaceRenames: vals.AllowWorkspaceRenames.Value(),
ProvisionerStrictTagPolicy: vals.Provisioner.StrictTagPolicy.Value(),
}
if httpServers.TLSConfig != nil {
options.TLSCertificates = httpServers.TLSConfig.Certificates

3
coderd/apidoc/docs.go generated
View File

@ -10675,6 +10675,9 @@ const docTemplate = `{
},
"force_cancel_interval": {
"type": "integer"
},
"strict_tag_policy": {
"type": "boolean"
}
}
},

View File

@ -9605,6 +9605,9 @@
},
"force_cancel_interval": {
"type": "integer"
},
"strict_tag_policy": {
"type": "boolean"
}
}
},

View File

@ -188,6 +188,8 @@ type Options struct {
// NewTicker is used for unit tests to replace "time.NewTicker".
NewTicker func(duration time.Duration) (tick <-chan time.Time, done func())
ProvisionerStrictTagPolicy bool
}
// @title Coder API
@ -363,6 +365,11 @@ func New(options *Options) *API {
ctx, cancel := context.WithCancel(context.Background())
r := chi.NewRouter()
acquirerOpts := make([]provisionerdserver.AcquirerOption, 0)
if options.ProvisionerStrictTagPolicy {
acquirerOpts = append(acquirerOpts, provisionerdserver.WithExactTagMatch())
}
// nolint:gocritic // Load deployment ID. This never changes
depID, err := options.Database.GetDeploymentID(dbauthz.AsSystemRestricted(ctx))
if err != nil {
@ -402,7 +409,9 @@ func New(options *Options) *API {
ctx,
options.Logger.Named("acquirer"),
options.Database,
options.Pubsub),
options.Pubsub,
acquirerOpts...,
),
}
api.AppearanceFetcher.Store(&appearance.DefaultFetcher)

View File

@ -146,6 +146,7 @@ type Options struct {
WorkspaceAppsStatsCollectorOptions workspaceapps.StatsCollectorOptions
AllowWorkspaceRenames bool
NewTicker func(duration time.Duration) (<-chan time.Time, func())
ProvisionerStrictTagPolicy bool
}
// New constructs a codersdk client connected to an in-memory API instance.
@ -453,6 +454,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
WorkspaceAppsStatsCollectorOptions: options.WorkspaceAppsStatsCollectorOptions,
AllowWorkspaceRenames: options.AllowWorkspaceRenames,
NewTicker: options.NewTicker,
ProvisionerStrictTagPolicy: options.ProvisionerStrictTagPolicy,
}
}

View File

@ -374,6 +374,7 @@ type ProvisionerConfig struct {
DaemonPollJitter clibase.Duration `json:"daemon_poll_jitter" typescript:",notnull"`
ForceCancelInterval clibase.Duration `json:"force_cancel_interval" typescript:",notnull"`
DaemonPSK clibase.String `json:"daemon_psk" typescript:",notnull"`
StrictTagPolicy clibase.Bool `json:"strict_tag_policy" typscript:",notnull"`
}
type RateLimitConfig struct {
@ -1410,6 +1411,16 @@ when required by your organization's security policy.`,
Group: &deploymentGroupProvisioning,
YAML: "daemonPSK",
},
{
Name: "Provisioner Strict Tag Policy",
Description: "If set to true, provisioner daemons will only acquire jobs having tags equal to the daemon's tags. Otherwise, allows provisioner daemons to acquire jobs having tags a subset of the daemon's tags. This applies to all provisioner daemons connected to coderd.",
Flag: "provisioner-strict-tag-policy",
Env: "CODER_PROVISIONER_STRICT_TAG_POLICY",
Value: &c.Provisioner.StrictTagPolicy,
Default: "false",
Group: &deploymentGroupProvisioning,
YAML: "strictTagPolicy",
},
// RateLimit settings
{
Name: "Disable All Rate Limits",

3
docs/api/general.md generated
View File

@ -327,7 +327,8 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
"daemon_psk": "string",
"daemons": 0,
"daemons_echo": true,
"force_cancel_interval": 0
"force_cancel_interval": 0,
"strict_tag_policy": true
},
"proxy_health_status_interval": 0,
"proxy_trusted_headers": ["string"],

10
docs/api/schemas.md generated
View File

@ -2320,7 +2320,8 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
"daemon_psk": "string",
"daemons": 0,
"daemons_echo": true,
"force_cancel_interval": 0
"force_cancel_interval": 0,
"strict_tag_policy": true
},
"proxy_health_status_interval": 0,
"proxy_trusted_headers": ["string"],
@ -2688,7 +2689,8 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
"daemon_psk": "string",
"daemons": 0,
"daemons_echo": true,
"force_cancel_interval": 0
"force_cancel_interval": 0,
"strict_tag_policy": true
},
"proxy_health_status_interval": 0,
"proxy_trusted_headers": ["string"],
@ -3985,7 +3987,8 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
"daemon_psk": "string",
"daemons": 0,
"daemons_echo": true,
"force_cancel_interval": 0
"force_cancel_interval": 0,
"strict_tag_policy": true
}
```
@ -3999,6 +4002,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
| `daemons` | integer | false | | |
| `daemons_echo` | boolean | false | | |
| `force_cancel_interval` | integer | false | | |
| `strict_tag_policy` | boolean | false | | |
## codersdk.ProvisionerDaemon

11
docs/cli/server.md generated
View File

@ -794,6 +794,17 @@ Pre-shared key to authenticate external provisioner daemons to Coder server.
Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.
### --provisioner-strict-tag-policy
| | |
| ----------- | ------------------------------------------------- |
| Type | <code>bool</code> |
| Environment | <code>$CODER_PROVISIONER_STRICT_TAG_POLICY</code> |
| YAML | <code>provisioning.strictTagPolicy</code> |
| Default | <code>false</code> |
If set to true, provisioner daemons will only acquire jobs having tags equal to the daemon's tags. Otherwise, allows provisioner daemons to acquire jobs having tags a subset of the daemon's tags. This applies to all provisioner daemons connected to coderd.
### --proxy-health-interval
| | |

View File

@ -554,4 +554,68 @@ func TestProvisionerDaemonServe(t *testing.T) {
require.NoError(t, err)
require.Len(t, daemons, 0)
})
t.Run("TagPolicyStrict", func(t *testing.T) {
t.Parallel()
// Start coderd with strict tag policy for provisionerd server.
client, user := coderdenttest.New(t, &coderdenttest.Options{
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureExternalProvisionerDaemons: 1,
},
},
ProvisionerDaemonPSK: "provisionersftw",
Options: &coderdtest.Options{
ProvisionerStrictTagPolicy: true,
},
})
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
another := codersdk.New(client.URL)
// Start
_, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
ID: uuid.New(),
Name: testutil.MustRandString(t, 63),
Organization: user.OrganizationID,
Provisioners: []codersdk.ProvisionerType{
codersdk.ProvisionerTypeEcho,
},
Tags: map[string]string{
provisionersdk.TagScope: provisionersdk.ScopeOrganization,
provisionersdk.TagOwner: "",
"foo": "bar",
},
PreSharedKey: "provisionersftw",
})
require.NoError(t, err)
daemons, err := client.ProvisionerDaemons(ctx) //nolint:gocritic // Test assertion.
require.NoError(t, err)
require.Len(t, daemons, 1)
// Create a template version build job with a tag.
data, err := echo.Tar(&echo.Responses{
Parse: echo.ParseComplete,
ProvisionPlan: echo.PlanComplete,
ProvisionApply: echo.ProvisionApplyWithAgent("testing"),
})
require.NoError(t, err)
//nolint:gocritic // Not testing file upload in this test.
file, err := client.Upload(ctx, codersdk.ContentTypeTar, bytes.NewReader(data))
require.NoError(t, err)
tv, err := client.CreateTemplateVersion(ctx, user.OrganizationID, codersdk.CreateTemplateVersionRequest{
Name: "example",
StorageMethod: codersdk.ProvisionerStorageMethodFile,
FileID: file.ID,
Provisioner: codersdk.ProvisionerTypeEcho,
ProvisionerTags: map[string]string{
provisionersdk.TagScope: provisionersdk.ScopeOrganization,
provisionersdk.TagOwner: "",
"foo": "bar",
},
})
require.NoError(t, err)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, tv.ID)
})
}

View File

@ -846,6 +846,7 @@ export interface ProvisionerConfig {
readonly daemon_poll_jitter: number;
readonly force_cancel_interval: number;
readonly daemon_psk: string;
readonly strict_tag_policy: boolean;
}
// From codersdk/provisionerdaemons.go