Skip to content

Commit 21ee167

Browse files
authored
Add plural names support to GetOpTypeAndResourceNameFromOpID (#223)
Issue #, if available: [#999](aws-controllers-k8s/community#999) Description of changes: * Heuristic to guess resource name will not singularize the resource, if defined in generator resource config. This is to support resources like EC2's DhcpOptions where there is no singular form of the resource. * unit test By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent f4166ae commit 21ee167

File tree

4 files changed

+94
-11
lines changed

4 files changed

+94
-11
lines changed

pkg/model/op.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818

1919
awssdkmodel "github.com/aws/aws-sdk-go/private/model/api"
2020
"github.com/gertd/go-pluralize"
21+
22+
ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/generate/config"
2123
)
2224

2325
type OpType int
@@ -43,26 +45,42 @@ type OperationMap map[OpType]map[string]*awssdkmodel.Operation
4345

4446
// GetOpTypeAndResourceNameFromOpID guesses the resource name and type of
4547
// operation from the OperationID
46-
func GetOpTypeAndResourceNameFromOpID(opID string) (OpType, string) {
48+
func GetOpTypeAndResourceNameFromOpID(
49+
opID string,
50+
cfg *ackgenconfig.Config,
51+
) (OpType, string) {
4752
pluralize := pluralize.NewClient()
4853
if strings.HasPrefix(opID, "CreateOrUpdate") {
4954
return OpTypeReplace, strings.TrimPrefix(opID, "CreateOrUpdate")
5055
} else if strings.HasPrefix(opID, "BatchCreate") {
5156
resName := strings.TrimPrefix(opID, "BatchCreate")
5257
if pluralize.IsPlural(resName) {
53-
return OpTypeCreateBatch, pluralize.Singular(resName)
58+
// Do not singularize "pluralized singular" resources
59+
// like EC2's DhcpOptions, if defined in generator config's list of
60+
// resources.
61+
if _, exists := cfg.Resources[resName]; !exists {
62+
return OpTypeCreateBatch, pluralize.Singular(resName)
63+
}
5464
}
5565
return OpTypeCreateBatch, resName
5666
} else if strings.HasPrefix(opID, "CreateBatch") {
5767
resName := strings.TrimPrefix(opID, "CreateBatch")
5868
if pluralize.IsPlural(resName) {
59-
return OpTypeCreateBatch, pluralize.Singular(resName)
69+
if _, exists := cfg.Resources[resName]; !exists {
70+
return OpTypeCreateBatch, pluralize.Singular(resName)
71+
}
6072
}
6173
return OpTypeCreateBatch, resName
6274
} else if strings.HasPrefix(opID, "Create") {
6375
resName := strings.TrimPrefix(opID, "Create")
6476
if pluralize.IsPlural(resName) {
65-
return OpTypeCreateBatch, pluralize.Singular(resName)
77+
// If resName exists in the generator configuration's list of
78+
// resources, then just return OpTypeCreate and the resource name.
79+
// This handles "pluralized singular" resource names like EC2's
80+
// DhcpOptions.
81+
if _, exists := cfg.Resources[resName]; !exists {
82+
return OpTypeCreateBatch, pluralize.Singular(resName)
83+
}
6684
}
6785
return OpTypeCreate, resName
6886
} else if strings.HasPrefix(opID, "Modify") {
@@ -74,7 +92,10 @@ func GetOpTypeAndResourceNameFromOpID(opID string) (OpType, string) {
7492
} else if strings.HasPrefix(opID, "Describe") {
7593
resName := strings.TrimPrefix(opID, "Describe")
7694
if pluralize.IsPlural(resName) {
77-
return OpTypeList, pluralize.Singular(resName)
95+
if _, exists := cfg.Resources[resName]; !exists {
96+
return OpTypeList, pluralize.Singular(resName)
97+
}
98+
return OpTypeList, resName
7899
}
79100
return OpTypeGet, resName
80101
} else if strings.HasPrefix(opID, "Get") {
@@ -85,12 +106,20 @@ func GetOpTypeAndResourceNameFromOpID(opID string) (OpType, string) {
85106
}
86107
resName := strings.TrimPrefix(opID, "Get")
87108
if pluralize.IsPlural(resName) {
88-
return OpTypeList, pluralize.Singular(resName)
109+
if _, exists := cfg.Resources[resName]; !exists {
110+
return OpTypeList, pluralize.Singular(resName)
111+
}
112+
return OpTypeList, resName
89113
}
90114
return OpTypeGet, resName
91115
} else if strings.HasPrefix(opID, "List") {
92116
resName := strings.TrimPrefix(opID, "List")
93-
return OpTypeList, pluralize.Singular(resName)
117+
if pluralize.IsPlural(resName) {
118+
if _, exists := cfg.Resources[resName]; !exists {
119+
return OpTypeList, pluralize.Singular(resName)
120+
}
121+
}
122+
return OpTypeList, resName
94123
} else if strings.HasPrefix(opID, "Set") {
95124
if strings.HasSuffix(opID, "Attributes") {
96125
resName := strings.TrimPrefix(opID, "Set")

pkg/model/op_test.go

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ package model_test
1616
import (
1717
"testing"
1818

19-
"github.com/aws-controllers-k8s/code-generator/pkg/model"
2019
"github.com/stretchr/testify/assert"
20+
21+
"github.com/aws-controllers-k8s/code-generator/pkg/model"
22+
"github.com/aws-controllers-k8s/code-generator/pkg/testutil"
2123
)
2224

2325
func TestGetOpTypeAndResourceNameFromOpID(t *testing.T) {
2426
assert := assert.New(t)
2527

28+
g := testutil.NewModelForService(t, "s3")
29+
2630
tests := []struct {
2731
opID string
2832
expOpType model.OpType
@@ -103,9 +107,54 @@ func TestGetOpTypeAndResourceNameFromOpID(t *testing.T) {
103107
model.OpTypeUnknown,
104108
"PauseEC2Instance",
105109
},
110+
// Heuristic should incorrectly parse DhcpOptions ops
111+
// due to resource not being in s3's generator config
112+
{
113+
"CreateDhcpOptions",
114+
model.OpTypeCreateBatch,
115+
"DhcpOption",
116+
},
117+
{
118+
"DescribeDhcpOptions",
119+
model.OpTypeList,
120+
"DhcpOption",
121+
},
122+
}
123+
for _, test := range tests {
124+
ot, resName := model.GetOpTypeAndResourceNameFromOpID(test.opID, g.GetConfig())
125+
assert.Equal(test.expOpType, ot, test.opID)
126+
assert.Equal(test.expResName, resName, test.opID)
127+
}
128+
}
129+
130+
func TestGetOpTypeAndResourceNameFromOpID_PluralSingular(t *testing.T) {
131+
assert := assert.New(t)
132+
133+
g := testutil.NewModelForService(t, "ec2")
134+
135+
tests := []struct {
136+
opID string
137+
expOpType model.OpType
138+
expResName string
139+
}{
140+
{
141+
"CreateDhcpOptions",
142+
model.OpTypeCreate,
143+
"DhcpOptions",
144+
},
145+
{
146+
"DescribeDhcpOptions",
147+
model.OpTypeList,
148+
"DhcpOptions",
149+
},
150+
{
151+
"DeleteDhcpOptions",
152+
model.OpTypeDelete,
153+
"DhcpOptions",
154+
},
106155
}
107156
for _, test := range tests {
108-
ot, resName := model.GetOpTypeAndResourceNameFromOpID(test.opID)
157+
ot, resName := model.GetOpTypeAndResourceNameFromOpID(test.opID, g.GetConfig())
109158
assert.Equal(test.expOpType, ot, test.opID)
110159
assert.Equal(test.expResName, resName, test.opID)
111160
}

pkg/model/sdk_helper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ func (a *SDKAPI) APIInterfaceTypeName() string {
382382

383383
// Override the operation type and/or resource name if specified in config
384384
func getOpTypeAndResourceName(opID string, cfg *ackgenconfig.Config) ([]OpType, string) {
385-
opType, resName := GetOpTypeAndResourceNameFromOpID(opID)
385+
opType, resName := GetOpTypeAndResourceNameFromOpID(opID, cfg)
386386
opTypes := []OpType{opType}
387387

388388
if cfg == nil {

pkg/testdata/models/apis/ec2/0000-00-00/generator.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
ignore:
22
field_paths:
33
- CreateVpcInput.DryRun
4+
- CreateDhcpOptionsInput.DryRun
45
resource_names:
56
- AccountAttribute
67
- CapacityReservation
@@ -10,6 +11,7 @@ ignore:
1011
- CustomerGateway
1112
- DefaultSubnet
1213
- DefaultVpc
14+
#- DhcpOptions
1315
- EgressOnlyInternetGateway
1416
- Fleet
1517
- FpgaImage
@@ -63,4 +65,7 @@ ignore:
6365

6466
operations:
6567
CreateVpcEndpoint:
66-
output_wrapper_field_path: VpcEndpoint
68+
output_wrapper_field_path: VpcEndpoint
69+
70+
resources:
71+
DhcpOptions:

0 commit comments

Comments
 (0)