Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3fddfef

Browse files
fix!: enforce agent names be case-insensitive-unique per-workspace (#16614)
Relates tocoder/coder-desktop-macos#54Currently, it's possible to have two agents within the same workspace whose names only differ in capitalization:This leads to an ambiguity in two cases:- For CoderVPN, we'd like to allow support to workspaces with a hostname of the form: `agent.workspace.username.coder`.- Workspace apps (`coder_app`s) currently use subdomains of the form: `<app>--<agent>--<workspace>--<username>(--<suffix>)?`.Of note is that DNS hosts must be strictly lower case, hence the ambiguity.This fix is technically a breaking change, but only for the incredibly rare use case where a user has:- A workspace with two agents- Those agent names differ only in capitalization.Those templates & workspaces will now fail to build. This can be fixed by choosing wholly unique names for the agents.
1 parent9f5ad23 commit3fddfef

File tree

4 files changed

+67
-4
lines changed

4 files changed

+67
-4
lines changed

‎coderd/provisionerdserver/provisionerdserver.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,10 +1891,12 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
18911891
appSlugs=make(map[string]struct{})
18921892
)
18931893
for_,prAgent:=rangeprotoResource.Agents {
1894-
if_,ok:=agentNames[prAgent.Name];ok {
1894+
// Agent names must be case-insensitive-unique, to be unambiguous in
1895+
// `coder_app`s and CoderVPN DNS names.
1896+
if_,ok:=agentNames[strings.ToLower(prAgent.Name)];ok {
18951897
returnxerrors.Errorf("duplicate agent name %q",prAgent.Name)
18961898
}
1897-
agentNames[prAgent.Name]=struct{}{}
1899+
agentNames[strings.ToLower(prAgent.Name)]=struct{}{}
18981900

18991901
varinstanceID sql.NullString
19001902
ifprAgent.GetInstanceId()!="" {

‎coderd/provisionerdserver/provisionerdserver_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,6 +1905,32 @@ func TestInsertWorkspaceResource(t *testing.T) {
19051905
})
19061906
require.ErrorContains(t,err,"duplicate app slug")
19071907
})
1908+
t.Run("DuplicateAgentNames",func(t*testing.T) {
1909+
t.Parallel()
1910+
db:=dbmem.New()
1911+
job:=uuid.New()
1912+
// case-insensitive-unique
1913+
err:=insert(db,job,&sdkproto.Resource{
1914+
Name:"something",
1915+
Type:"aws_instance",
1916+
Agents: []*sdkproto.Agent{{
1917+
Name:"dev",
1918+
}, {
1919+
Name:"Dev",
1920+
}},
1921+
})
1922+
require.ErrorContains(t,err,"duplicate agent name")
1923+
err=insert(db,job,&sdkproto.Resource{
1924+
Name:"something",
1925+
Type:"aws_instance",
1926+
Agents: []*sdkproto.Agent{{
1927+
Name:"dev",
1928+
}, {
1929+
Name:"dev",
1930+
}},
1931+
})
1932+
require.ErrorContains(t,err,"duplicate agent name")
1933+
})
19081934
t.Run("Success",func(t*testing.T) {
19091935
t.Parallel()
19101936
db:=dbmem.New()

‎provisioner/terraform/resources.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,12 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s
215215
returnnil,xerrors.Errorf("decode agent attributes: %w",err)
216216
}
217217

218-
if_,ok:=agentNames[tfResource.Name];ok {
218+
// Agent names must be case-insensitive-unique, to be unambiguous in
219+
// `coder_app`s and CoderVPN DNS names.
220+
if_,ok:=agentNames[strings.ToLower(tfResource.Name)];ok {
219221
returnnil,xerrors.Errorf("duplicate agent name: %s",tfResource.Name)
220222
}
221-
agentNames[tfResource.Name]=struct{}{}
223+
agentNames[strings.ToLower(tfResource.Name)]=struct{}{}
222224

223225
// Handling for deprecated attributes. login_before_ready was replaced
224226
// by startup_script_behavior, but we still need to support it for

‎provisioner/terraform/resources_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,39 @@ func TestAppSlugValidation(t *testing.T) {
10261026
require.ErrorContains(t,err,"duplicate app slug")
10271027
}
10281028

1029+
funcTestAgentNameDuplicate(t*testing.T) {
1030+
t.Parallel()
1031+
ctx,logger:=ctxAndLogger(t)
1032+
1033+
// nolint:dogsled
1034+
_,filename,_,_:=runtime.Caller(0)
1035+
1036+
dir:=filepath.Join(filepath.Dir(filename),"testdata","multiple-agents")
1037+
tfPlanRaw,err:=os.ReadFile(filepath.Join(dir,"multiple-agents.tfplan.json"))
1038+
require.NoError(t,err)
1039+
vartfPlan tfjson.Plan
1040+
err=json.Unmarshal(tfPlanRaw,&tfPlan)
1041+
require.NoError(t,err)
1042+
tfPlanGraph,err:=os.ReadFile(filepath.Join(dir,"multiple-agents.tfplan.dot"))
1043+
require.NoError(t,err)
1044+
1045+
for_,resource:=rangetfPlan.PlannedValues.RootModule.Resources {
1046+
ifresource.Type=="coder_agent" {
1047+
switchresource.Name {
1048+
case"dev1":
1049+
resource.Name="dev"
1050+
case"dev2":
1051+
resource.Name="Dev"
1052+
}
1053+
}
1054+
}
1055+
1056+
state,err:=terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PlannedValues.RootModule},string(tfPlanGraph),logger)
1057+
require.Nil(t,state)
1058+
require.Error(t,err)
1059+
require.ErrorContains(t,err,"duplicate agent name")
1060+
}
1061+
10291062
funcTestMetadataResourceDuplicate(t*testing.T) {
10301063
t.Parallel()
10311064
ctx,logger:=ctxAndLogger(t)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp