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

Commit125e9ef

Browse files
authored
fix: validate that parameter names are unique (#7882)
1 parentfbdbc8a commit125e9ef

File tree

4 files changed

+125
-0
lines changed

4 files changed

+125
-0
lines changed

‎coderd/util/strings/strings.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package strings
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
// JoinWithConjunction joins a slice of strings with commas except for the last
9+
// two which are joined with "and".
10+
funcJoinWithConjunction(s []string)string {
11+
last:=len(s)-1
12+
iflast==0 {
13+
returns[last]
14+
}
15+
returnfmt.Sprintf("%s and %s",
16+
strings.Join(s[:last],", "),
17+
s[last],
18+
)
19+
}

‎coderd/util/strings/strings_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package strings_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/coder/coder/coderd/util/strings"
9+
)
10+
11+
funcTestJoinWithConjunction(t*testing.T) {
12+
t.Parallel()
13+
require.Equal(t,"foo",strings.JoinWithConjunction([]string{"foo"}))
14+
require.Equal(t,"foo and bar",strings.JoinWithConjunction([]string{"foo","bar"}))
15+
require.Equal(t,"foo, bar and baz",strings.JoinWithConjunction([]string{"foo","bar","baz"}))
16+
}

‎provisioner/terraform/resources.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package terraform
22

33
import (
4+
"fmt"
45
"strings"
56

67
"github.com/awalterschulze/gographviz"
@@ -10,6 +11,8 @@ import (
1011

1112
"github.com/coder/terraform-provider-coder/provider"
1213

14+
"github.com/coder/coder/coderd/util/slice"
15+
stringutil"github.com/coder/coder/coderd/util/strings"
1316
"github.com/coder/coder/codersdk"
1417
"github.com/coder/coder/provisioner"
1518
"github.com/coder/coder/provisionersdk/proto"
@@ -473,6 +476,7 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string, rawParameterNa
473476
}
474477
}
475478

479+
varduplicatedParamNames []string
476480
parameters:=make([]*proto.RichParameter,0)
477481
for_,resource:=rangeorderedRichParametersResources(tfResourcesRichParameters,rawParameterNames) {
478482
varparam provider.Parameter
@@ -536,9 +540,31 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string, rawParameterNa
536540
})
537541
}
538542
}
543+
544+
// Check if this parameter duplicates an existing parameter.
545+
formattedName:=fmt.Sprintf("%q",protoParam.Name)
546+
if!slice.Contains(duplicatedParamNames,formattedName)&&
547+
slice.ContainsCompare(parameters,protoParam,func(a,b*proto.RichParameter)bool {
548+
returna.Name==b.Name
549+
}) {
550+
duplicatedParamNames=append(duplicatedParamNames,formattedName)
551+
}
552+
539553
parameters=append(parameters,protoParam)
540554
}
541555

556+
// Enforce that parameters be uniquely named.
557+
iflen(duplicatedParamNames)>0 {
558+
s:=""
559+
iflen(duplicatedParamNames)==1 {
560+
s="s"
561+
}
562+
returnnil,xerrors.Errorf(
563+
"coder_parameter names must be unique but %s appear%s multiple times",
564+
stringutil.JoinWithConjunction(duplicatedParamNames),s,
565+
)
566+
}
567+
542568
// A map is used to ensure we don't have duplicates!
543569
gitAuthProvidersMap:=map[string]struct{}{}
544570
for_,tfResources:=rangetfResourcesByLabel {

‎provisioner/terraform/resources_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package terraform_test
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"os"
67
"path/filepath"
78
"runtime"
@@ -584,6 +585,69 @@ func TestAppSlugValidation(t *testing.T) {
584585
require.ErrorContains(t,err,"duplicate app slug")
585586
}
586587

588+
funcTestParameterValidation(t*testing.T) {
589+
t.Parallel()
590+
591+
// nolint:dogsled
592+
_,filename,_,_:=runtime.Caller(0)
593+
594+
// Load the rich-parameters state file and edit it.
595+
dir:=filepath.Join(filepath.Dir(filename),"testdata","rich-parameters")
596+
tfPlanRaw,err:=os.ReadFile(filepath.Join(dir,"rich-parameters.tfplan.json"))
597+
require.NoError(t,err)
598+
vartfPlan tfjson.Plan
599+
err=json.Unmarshal(tfPlanRaw,&tfPlan)
600+
require.NoError(t,err)
601+
tfPlanGraph,err:=os.ReadFile(filepath.Join(dir,"rich-parameters.tfplan.dot"))
602+
require.NoError(t,err)
603+
604+
// Change all names to be identical.
605+
varnames []string
606+
for_,resource:=rangetfPlan.PriorState.Values.RootModule.Resources {
607+
ifresource.Type=="coder_parameter" {
608+
resource.AttributeValues["name"]="identical"
609+
names=append(names,resource.Name)
610+
}
611+
}
612+
613+
state,err:=terraform.ConvertState([]*tfjson.StateModule{tfPlan.PriorState.Values.RootModule},string(tfPlanGraph),names)
614+
require.Nil(t,state)
615+
require.Error(t,err)
616+
require.ErrorContains(t,err,"coder_parameter names must be unique but\"identical\" appears multiple times")
617+
618+
// Make two sets of identical names.
619+
count:=0
620+
names=nil
621+
for_,resource:=rangetfPlan.PriorState.Values.RootModule.Resources {
622+
ifresource.Type=="coder_parameter" {
623+
resource.AttributeValues["name"]=fmt.Sprintf("identical-%d",count%2)
624+
names=append(names,resource.Name)
625+
count++
626+
}
627+
}
628+
629+
state,err=terraform.ConvertState([]*tfjson.StateModule{tfPlan.PriorState.Values.RootModule},string(tfPlanGraph),names)
630+
require.Nil(t,state)
631+
require.Error(t,err)
632+
require.ErrorContains(t,err,"coder_parameter names must be unique but\"identical-0\" and\"identical-1\" appear multiple times")
633+
634+
// Once more with three sets.
635+
count=0
636+
names=nil
637+
for_,resource:=rangetfPlan.PriorState.Values.RootModule.Resources {
638+
ifresource.Type=="coder_parameter" {
639+
resource.AttributeValues["name"]=fmt.Sprintf("identical-%d",count%3)
640+
names=append(names,resource.Name)
641+
count++
642+
}
643+
}
644+
645+
state,err=terraform.ConvertState([]*tfjson.StateModule{tfPlan.PriorState.Values.RootModule},string(tfPlanGraph),names)
646+
require.Nil(t,state)
647+
require.Error(t,err)
648+
require.ErrorContains(t,err,"coder_parameter names must be unique but\"identical-0\",\"identical-1\" and\"identical-2\" appear multiple times")
649+
}
650+
587651
funcTestInstanceTypeAssociation(t*testing.T) {
588652
t.Parallel()
589653
typetcstruct {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp