Skip to content

Commit 79b8dd7

Browse files
Load service model name from generator (#216)
Fixes aws-controllers-k8s/community#994 Description of changes: This pull request supports including an optional `model_name` field in the `generator.yaml` file. The generator will use this argument to override the service name when looking up the API files in aws-sdk-go/models/apis. Currently `ServiceIDClean` is used in all code generator templates as the import path for aws-sdk-go and when referencing the controller name (eg. `{{ .ServiceIDClean}}-controller`). This pull request will remove `ServiceIDClean` and instead use the service alias (as `ServiceAlias`) when referencing the controller and the aws-sdk-go packages. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent eaa7f22 commit 79b8dd7

37 files changed

+192
-197
lines changed

cmd/ack-generate/command/apis.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424

2525
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
2626
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
27-
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
2827
"github.com/aws-controllers-k8s/code-generator/pkg/util"
2928
)
3029

@@ -97,25 +96,11 @@ func generateAPIs(cmd *cobra.Command, args []string) error {
9796
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
9897
return err
9998
}
100-
sdkHelper := ackmodel.NewSDKHelper(sdkDir)
101-
sdkAPI, err := sdkHelper.API(svcAlias)
102-
if err != nil {
103-
newSvcAlias, err := FallBackFindServiceID(sdkDir, svcAlias)
104-
if err != nil {
105-
return err
106-
}
107-
sdkAPI, err = sdkHelper.API(newSvcAlias) // retry with serviceID
108-
if err != nil {
109-
return fmt.Errorf("service %s not found", svcAlias)
110-
}
111-
}
112-
model, err := ackmodel.New(
113-
sdkAPI, optGenVersion, optGeneratorConfigPath, ackgenerate.DefaultConfig,
114-
)
99+
m, err := loadModelWithLatestAPIVersion(svcAlias)
115100
if err != nil {
116101
return err
117102
}
118-
ts, err := ackgenerate.APIs(model, optTemplateDirs)
103+
ts, err := ackgenerate.APIs(m, optTemplateDirs)
119104
if err != nil {
120105
return err
121106
}

cmd/ack-generate/command/common.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,18 @@ import (
2020
"os"
2121
"os/signal"
2222
"path/filepath"
23+
"sort"
2324
"strings"
2425
"syscall"
2526
"time"
2627

2728
"golang.org/x/mod/modfile"
2829

30+
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
31+
ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/generate/config"
32+
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
2933
"github.com/aws-controllers-k8s/code-generator/pkg/util"
34+
k8sversion "k8s.io/apimachinery/pkg/version"
3035
)
3136

3237
const (
@@ -207,3 +212,68 @@ func getSDKVersionFromGoMod(goModPath string) (string, error) {
207212
}
208213
return "", fmt.Errorf("couldn't find %s in the go.mod require block", sdkModule)
209214
}
215+
216+
// loadModelWithLatestAPIVersion finds the AWS SDK for a given service alias and
217+
// creates a new model with the latest API version.
218+
func loadModelWithLatestAPIVersion(svcAlias string) (*ackmodel.Model, error) {
219+
latestAPIVersion, err := getLatestAPIVersion()
220+
if err != nil {
221+
return nil, err
222+
}
223+
return loadModel(svcAlias, latestAPIVersion)
224+
}
225+
226+
// loadModel finds the AWS SDK for a given service alias and creates a new model
227+
// with the given API version.
228+
func loadModel(svcAlias string, apiVersion string) (*ackmodel.Model, error) {
229+
cfg, err := ackgenconfig.New(optGeneratorConfigPath, ackgenerate.DefaultConfig)
230+
if err != nil {
231+
return nil, err
232+
}
233+
234+
modelName := strings.ToLower(cfg.ModelName)
235+
if modelName == "" {
236+
modelName = svcAlias
237+
}
238+
239+
sdkHelper := ackmodel.NewSDKHelper(sdkDir)
240+
sdkAPI, err := sdkHelper.API(modelName)
241+
if err != nil {
242+
retryModelName, err := FallBackFindServiceID(sdkDir, svcAlias)
243+
if err != nil {
244+
return nil, err
245+
}
246+
// Retry using path found by querying service ID
247+
sdkAPI, err = sdkHelper.API(retryModelName)
248+
if err != nil {
249+
return nil, fmt.Errorf("service %s not found", svcAlias)
250+
}
251+
}
252+
m, err := ackmodel.New(
253+
sdkAPI, svcAlias, apiVersion, cfg,
254+
)
255+
if err != nil {
256+
return nil, err
257+
}
258+
return m, nil
259+
}
260+
261+
// getLatestAPIVersion looks in a target output directory to determine what the
262+
// latest Kubernetes API version for CRDs exposed by the generated service
263+
// controller.
264+
func getLatestAPIVersion() (string, error) {
265+
apisPath := filepath.Join(optOutputPath, "apis")
266+
versions := []string{}
267+
subdirs, err := ioutil.ReadDir(apisPath)
268+
if err != nil {
269+
return "", err
270+
}
271+
272+
for _, subdir := range subdirs {
273+
versions = append(versions, subdir.Name())
274+
}
275+
sort.Slice(versions, func(i, j int) bool {
276+
return k8sversion.CompareKubeAwareVersionStrings(versions[i], versions[j]) < 0
277+
})
278+
return versions[len(versions)-1], nil
279+
}

cmd/ack-generate/command/controller.go

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@ import (
2121
"os"
2222
"path/filepath"
2323
"regexp"
24-
"sort"
2524
"strings"
2625

2726
"github.com/spf13/cobra"
28-
k8sversion "k8s.io/apimachinery/pkg/version"
2927

3028
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
31-
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
3229
)
3330

3431
var (
@@ -62,25 +59,7 @@ func generateController(cmd *cobra.Command, args []string) error {
6259
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
6360
return err
6461
}
65-
sdkHelper := ackmodel.NewSDKHelper(sdkDir)
66-
sdkAPI, err := sdkHelper.API(svcAlias)
67-
if err != nil {
68-
newSvcAlias, err := FallBackFindServiceID(sdkDir, svcAlias)
69-
if err != nil {
70-
return err
71-
}
72-
sdkAPI, err = sdkHelper.API(newSvcAlias) // retry with serviceID
73-
if err != nil {
74-
return fmt.Errorf("service %s not found", svcAlias)
75-
}
76-
}
77-
latestAPIVersion, err = getLatestAPIVersion()
78-
if err != nil {
79-
return err
80-
}
81-
m, err := ackmodel.New(
82-
sdkAPI, latestAPIVersion, optGeneratorConfigPath, ackgenerate.DefaultConfig,
83-
)
62+
m, err := loadModelWithLatestAPIVersion(svcAlias)
8463
if err != nil {
8564
return err
8665
}
@@ -111,26 +90,6 @@ func generateController(cmd *cobra.Command, args []string) error {
11190
return nil
11291
}
11392

114-
// getLatestAPIVersion looks in a target output directory to determine what the
115-
// latest Kubernetes API version for CRDs exposed by the generated service
116-
// controller.
117-
func getLatestAPIVersion() (string, error) {
118-
apisPath := filepath.Join(optOutputPath, "apis")
119-
versions := []string{}
120-
subdirs, err := ioutil.ReadDir(apisPath)
121-
if err != nil {
122-
return "", err
123-
}
124-
125-
for _, subdir := range subdirs {
126-
versions = append(versions, subdir.Name())
127-
}
128-
sort.Slice(versions, func(i, j int) bool {
129-
return k8sversion.CompareKubeAwareVersionStrings(versions[i], versions[j]) < 0
130-
})
131-
return versions[len(versions)-1], nil
132-
}
133-
13493
// FallBackFindServiceID reads through aws-sdk-go/models/apis/*/*/api-2.json
13594
// Returns ServiceID (as newSuppliedAlias) if supplied service Alias matches with serviceID in api-2.json
13695
// If not a match, return the supllied alias.

cmd/ack-generate/command/crossplane.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
"github.com/pkg/errors"
2626
"github.com/spf13/cobra"
2727

28+
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
29+
ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/generate/config"
2830
cpgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/crossplane"
2931
"github.com/aws-controllers-k8s/code-generator/pkg/model"
3032
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
@@ -56,6 +58,18 @@ func generateCrossplane(_ *cobra.Command, args []string) error {
5658
return err
5759
}
5860
svcAlias := strings.ToLower(args[0])
61+
cfgPath := filepath.Join(providerDir, "apis", svcAlias, optGenVersion, "generator-config.yaml")
62+
_, err := os.Stat(cfgPath)
63+
if err != nil && !os.IsNotExist(err) {
64+
return err
65+
}
66+
if os.IsNotExist(err) {
67+
cfgPath = ""
68+
}
69+
cfg, err := ackgenconfig.New(cfgPath, ackgenerate.DefaultConfig)
70+
if err != nil {
71+
return err
72+
}
5973
sdkHelper := model.NewSDKHelper(sdkDir)
6074
sdkHelper.APIGroupSuffix = "aws.crossplane.io"
6175
sdkAPI, err := sdkHelper.API(svcAlias)
@@ -69,16 +83,8 @@ func generateCrossplane(_ *cobra.Command, args []string) error {
6983
return fmt.Errorf("cannot get the API model for service %s", svcAlias)
7084
}
7185
}
72-
cfgPath := filepath.Join(providerDir, "apis", svcAlias, optGenVersion, "generator-config.yaml")
73-
_, err = os.Stat(cfgPath)
74-
if err != nil && !os.IsNotExist(err) {
75-
return err
76-
}
77-
if os.IsNotExist(err) {
78-
cfgPath = ""
79-
}
8086
m, err := ackmodel.New(
81-
sdkAPI, optGenVersion, cfgPath, cpgenerate.DefaultConfig,
87+
sdkAPI, svcAlias, optGenVersion, cfg,
8288
)
8389
if err != nil {
8490
return err

cmd/ack-generate/command/olm.go

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ import (
2323
"github.com/ghodss/yaml"
2424
"github.com/spf13/cobra"
2525

26-
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
2726
olmgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/olm"
28-
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
2927
)
3028

3129
const (
@@ -86,26 +84,7 @@ func generateOLMAssets(cmd *cobra.Command, args []string) error {
8684
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
8785
return err
8886
}
89-
sdkHelper := ackmodel.NewSDKHelper(sdkDir)
90-
sdkAPI, err := sdkHelper.API(svcAlias)
91-
if err != nil {
92-
newSvcAlias, err := FallBackFindServiceID(sdkDir, svcAlias)
93-
if err != nil {
94-
return err
95-
}
96-
sdkAPI, err = sdkHelper.API(newSvcAlias) // retry with serviceID
97-
if err != nil {
98-
return fmt.Errorf("service %s not found", svcAlias)
99-
}
100-
}
101-
102-
latestAPIVersion, err = getLatestAPIVersion()
103-
if err != nil {
104-
return err
105-
}
106-
m, err := ackmodel.New(
107-
sdkAPI, latestAPIVersion, optGeneratorConfigPath, ackgenerate.DefaultConfig,
108-
)
87+
m, err := loadModelWithLatestAPIVersion(svcAlias)
10988
if err != nil {
11089
return err
11190
}

cmd/ack-generate/command/release.go

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424

2525
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
2626
ackmetadata "github.com/aws-controllers-k8s/code-generator/pkg/metadata"
27-
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
2827
)
2928

3029
var (
@@ -74,21 +73,7 @@ func generateRelease(cmd *cobra.Command, args []string) error {
7473
if err := ensureSDKRepo(ctx, optCacheDir, optRefreshCache); err != nil {
7574
return err
7675
}
77-
sdkHelper := ackmodel.NewSDKHelper(sdkDir)
78-
sdkAPI, err := sdkHelper.API(svcAlias)
79-
if err != nil {
80-
newSvcAlias, err := FallBackFindServiceID(sdkDir, svcAlias)
81-
if err != nil {
82-
return err
83-
}
84-
sdkAPI, err = sdkHelper.API(newSvcAlias) // retry with serviceID
85-
if err != nil {
86-
return fmt.Errorf("service %s not found", svcAlias)
87-
}
88-
}
89-
m, err := ackmodel.New(
90-
sdkAPI, "", optGeneratorConfigPath, ackgenerate.DefaultConfig,
91-
)
76+
m, err := loadModel(svcAlias, "")
9277
if err != nil {
9378
return err
9479
}

pkg/generate/config/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ type Config struct {
3939
// SetManyOutput function fails with NotFound error.
4040
// Default is "return nil, ackerr.NotFound"
4141
SetManyOutputNotFoundErrReturn string `json:"set_many_output_notfound_err_return,omitempty"`
42+
// ModelName lets you specify the path used to identify the AWS service API
43+
// in the aws-sdk-go's models/apis/ directory. This field is optional and
44+
// only needed for services such as the opensearchservice service where the
45+
// model name is `opensearch` and the service package is called
46+
// `opensearchservice`.
47+
ModelName string `json:"model_name,omitempty"`
4248
}
4349

4450
// IgnoreSpec represents instructions to the ACK code generator to

pkg/generate/crossplane/crossplane.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func Crossplane(
145145
for _, path := range apisGenericTemplatesPaths {
146146
outPath := filepath.Join(
147147
"apis",
148-
metaVars.ServiceIDClean,
148+
metaVars.ServiceAlias,
149149
metaVars.APIVersion,
150150
"zz_"+strings.TrimSuffix(filepath.Base(path), ".tpl"),
151151
)
@@ -155,7 +155,7 @@ func Crossplane(
155155
}
156156
for _, crd := range crds {
157157
crdFileName := filepath.Join(
158-
"apis", metaVars.ServiceIDClean, metaVars.APIVersion,
158+
"apis", metaVars.ServiceAlias, metaVars.APIVersion,
159159
"zz_"+strcase.ToSnake(crd.Kind)+".go",
160160
)
161161
crdVars := &templateCRDVars{
@@ -170,7 +170,7 @@ func Crossplane(
170170
// Next add the controller package for each CRD
171171
for _, crd := range crds {
172172
outPath := filepath.Join(
173-
"pkg", "controller", metaVars.ServiceIDClean, crd.Names.Lower,
173+
"pkg", "controller", metaVars.ServiceAlias, crd.Names.Lower,
174174
"zz_controller.go",
175175
)
176176
crdVars := &templateCRDVars{
@@ -181,7 +181,7 @@ func Crossplane(
181181
return nil, err
182182
}
183183
outPath = filepath.Join(
184-
"pkg", "controller", metaVars.ServiceIDClean, crd.Names.Lower,
184+
"pkg", "controller", metaVars.ServiceAlias, crd.Names.Lower,
185185
"zz_conversions.go",
186186
)
187187
crdVars = &templateCRDVars{

pkg/generate/olm/olm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func BundleAssets(
7979

8080
csvBaseOutPath := fmt.Sprintf(
8181
"config/manifests/bases/ack-%s-controller.clusterserviceversion.yaml",
82-
m.MetaVars().ServiceIDClean)
82+
m.MetaVars().ServiceAlias)
8383
if err := ts.Add(csvBaseOutPath, "config/manifests/bases/clusterserviceversion.yaml.tpl", olmVars); err != nil {
8484
return nil, err
8585
}

pkg/generate/templateset/vars.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@ package templateset
1717
// that describe the service alias, its package name, etc
1818
type MetaVars struct {
1919
// ServiceAlias contains the exact string used to identify the AWS service
20-
// API in the aws-sdk-go's models/apis/ directory. Note that some APIs this
21-
// alias does not match the ServiceID. e.g. The AWS Step Functions API has
22-
// a ServiceID of "SFN" and a service alias of "states"...
20+
// API in the aws-sdk-go `service/` directory. It is also used as the
21+
// identifier for the ACK controller's name and packages.
2322
ServiceAlias string
2423
// ServiceID is the exact string that appears in the AWS service API's
2524
// api-2.json descriptor file under `metadata.serviceId`
2625
ServiceID string
27-
// ServiceIDClean is the ServiceID lowercased and stripped of any
28-
// non-alphanumeric characters
29-
ServiceIDClean string
26+
// ServiceModelName contains the exact string used to identify the AWS
27+
// service API in the aws-sdk-go's models/apis/ directory. Note that some
28+
// APIs this name does not match the ServiceID. e.g. The AWS Step Functions
29+
// API has a ServiceID of "SFN" and a service model name of "states"...
30+
ServiceModelName string
3031
// APIVersion contains the version of the Kubernetes API resources, e.g.
3132
// "v1alpha1"
3233
APIVersion string

0 commit comments

Comments
 (0)