14
14
package model
15
15
16
16
import (
17
- "errors"
18
- "fmt"
19
- "io/ioutil"
20
- "os"
21
- "path/filepath"
22
- "sort"
23
17
"strings"
24
18
25
- "gopkg.in/src-d/go-git.v4 "
19
+ awssdkmodel "github.com/aws/aws-sdk-go/private/model/api "
26
20
27
21
ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/generate/config"
28
22
"github.com/aws-controllers-k8s/code-generator/pkg/names"
29
23
"github.com/aws-controllers-k8s/code-generator/pkg/util"
30
-
31
- awssdkmodel "github.com/aws/aws-sdk-go/private/model/api"
32
24
)
33
25
34
- var (
35
- ErrInvalidVersionDirectory = errors .New (
36
- "expected to find only directories in api model directory but found non-directory" ,
37
- )
38
- ErrNoValidVersionDirectory = errors .New (
39
- "no valid version directories found" ,
40
- )
41
- ErrServiceNotFound = errors .New (
42
- "no such service" ,
43
- )
44
- ErrAPIVersionNotFound = errors .New (
45
- "no such api version" ,
46
- )
26
+ const (
27
+ // ConflictingNameSuffix is appended to type names when they overlap with
28
+ // well-known common struct names for things like a CRD itself, or its
29
+ // Spec/Status subfield struct type name.
30
+ ConflictingNameSuffix = "_SDK"
47
31
)
48
32
49
- // SDKHelper is a helper struct that helps work with the aws-sdk-go models and
50
- // API model loader
51
- type SDKHelper struct {
52
- gitRepository * git.Repository
53
- basePath string
54
- loader * awssdkmodel.Loader
55
- // Default is set by `FirstAPIVersion`
56
- apiVersion string
57
- // Default is "services.k8s.aws"
58
- APIGroupSuffix string
59
- }
60
-
61
- // NewSDKHelper returns a new SDKHelper object
62
- func NewSDKHelper (basePath string ) * SDKHelper {
63
- return & SDKHelper {
64
- basePath : basePath ,
65
- loader : & awssdkmodel.Loader {
66
- BaseImport : basePath ,
67
- IgnoreUnsupportedAPIs : true ,
68
- },
69
- }
70
- }
71
-
72
- // WithSDKVersion checks out the sdk git repository to the provided version. To use
73
- // this function h.basePath should point to a git repository.
74
- func (h * SDKHelper ) WithSDKVersion (version string ) error {
75
- if h .gitRepository == nil {
76
- gitRepository , err := util .LoadRepository (h .basePath )
77
- if err != nil {
78
- return fmt .Errorf ("error loading repository from %s: %v" , h .basePath , err )
79
- }
80
- h .gitRepository = gitRepository
81
- }
82
-
83
- err := util .CheckoutRepositoryTag (h .gitRepository , version )
84
- if err != nil {
85
- return fmt .Errorf ("cannot checkout tag %s: %v" , version , err )
86
- }
87
- return nil
88
- }
89
-
90
- // WithAPIVersion sets the `apiVersion` field.
91
- func (h * SDKHelper ) WithAPIVersion (apiVersion string ) {
92
- h .apiVersion = apiVersion
93
- }
94
-
95
- // API returns the aws-sdk-go API model for a supplied service model name.
96
- func (h * SDKHelper ) API (serviceModelName string ) (* SDKAPI , error ) {
97
- modelPath , _ , err := h .ModelAndDocsPath (serviceModelName )
98
- if err != nil {
99
- return nil , err
100
- }
101
- apis , err := h .loader .Load ([]string {modelPath })
102
- if err != nil {
103
- return nil , err
104
- }
105
- // apis is a map, keyed by the service alias, of pointers to aws-sdk-go
106
- // model API objects
107
- for _ , api := range apis {
108
- // If we don't do this, we can end up with panic()'s like this:
109
- // panic: assignment to entry in nil map
110
- // when trying to execute Shape.GoType().
111
- //
112
- // Calling API.ServicePackageDoc() ends up resetting the API.imports
113
- // unexported map variable...
114
- _ = api .ServicePackageDoc ()
115
- return & SDKAPI {api , nil , nil , h .APIGroupSuffix }, nil
116
- }
117
- return nil , ErrServiceNotFound
118
- }
119
-
120
- // ModelAndDocsPath returns two string paths to the supplied service's API and
121
- // doc JSON files
122
- func (h * SDKHelper ) ModelAndDocsPath (
123
- serviceModelName string ,
124
- ) (string , string , error ) {
125
- if h .apiVersion == "" {
126
- apiVersion , err := h .FirstAPIVersion (serviceModelName )
127
- if err != nil {
128
- return "" , "" , err
129
- }
130
- h .apiVersion = apiVersion
131
- }
132
- versionPath := filepath .Join (
133
- h .basePath , "models" , "apis" , serviceModelName , h .apiVersion ,
134
- )
135
- modelPath := filepath .Join (versionPath , "api-2.json" )
136
- docsPath := filepath .Join (versionPath , "docs-2.json" )
137
- return modelPath , docsPath , nil
138
- }
139
-
140
- // FirstAPIVersion returns the first found API version for a service API.
141
- // (e.h. "2012-10-03")
142
- func (h * SDKHelper ) FirstAPIVersion (serviceModelName string ) (string , error ) {
143
- versions , err := h .GetAPIVersions (serviceModelName )
144
- if err != nil {
145
- return "" , err
146
- }
147
- sort .Strings (versions )
148
- return versions [0 ], nil
149
- }
150
-
151
- // GetAPIVersions returns the list of API Versions found in a service directory.
152
- func (h * SDKHelper ) GetAPIVersions (serviceModelName string ) ([]string , error ) {
153
- apiPath := filepath .Join (h .basePath , "models" , "apis" , serviceModelName )
154
- versionDirs , err := ioutil .ReadDir (apiPath )
155
- if err != nil {
156
- return nil , err
157
- }
158
- versions := []string {}
159
- for _ , f := range versionDirs {
160
- version := f .Name ()
161
- fp := filepath .Join (apiPath , version )
162
- fi , err := os .Lstat (fp )
163
- if err != nil {
164
- return nil , err
165
- }
166
- if ! fi .IsDir () {
167
- return nil , fmt .Errorf ("found %s: %v" , version , ErrInvalidVersionDirectory )
168
- }
169
- versions = append (versions , version )
170
- }
171
- if len (versions ) == 0 {
172
- return nil , ErrNoValidVersionDirectory
173
- }
174
- return versions , nil
175
- }
176
-
177
33
// SDKAPI contains an API model for a single AWS service API
178
34
type SDKAPI struct {
179
- API * awssdkmodel.API
35
+ API * awssdkmodel.API
36
+ APIGroupSuffix string
180
37
// A map of operation type and resource name to
181
38
// aws-sdk-go/private/model/api.Operation structs
182
39
opMap * OperationMap
183
40
// Map, keyed by original Shape GoTypeElem(), with the values being a
184
41
// renamed type name (due to conflicting names)
185
42
typeRenames map [string ]string
186
43
// Default is "services.k8s.aws"
187
- apiGroupSuffix string
188
44
}
189
45
190
46
// GetPayloads returns a slice of strings of Shape names representing input and
@@ -245,41 +101,6 @@ func (a *SDKAPI) GetOutputShapeRef(
245
101
return getMemberByPath (op .OutputRef .Shape , path )
246
102
}
247
103
248
- // getMemberByPath returns a ShapeRef given a root Shape and a dot-notation
249
- // object search path. Given the explicit type check for list type members
250
- // both ".." and "." notations work currently.
251
- // TODO: Add support for other types such as map.
252
- func getMemberByPath (
253
- shape * awssdkmodel.Shape ,
254
- path string ,
255
- ) (* awssdkmodel.ShapeRef , bool ) {
256
- elements := strings .Split (path , "." )
257
- last := len (elements ) - 1
258
- for x , elem := range elements {
259
- if elem == "" {
260
- continue
261
- }
262
- if shape == nil {
263
- return nil , false
264
- }
265
- shapeRef , ok := shape .MemberRefs [elem ]
266
- if ! ok {
267
- return nil , false
268
- }
269
- if x == last {
270
- return shapeRef , true
271
- }
272
- elemType := shapeRef .Shape .Type
273
- switch elemType {
274
- case "list" :
275
- shape = shapeRef .Shape .MemberRef .Shape
276
- default :
277
- shape = shapeRef .Shape
278
- }
279
- }
280
- return nil , false
281
- }
282
-
283
104
// CRDNames returns a slice of names structs for all top-level resources in the
284
105
// API
285
106
func (a * SDKAPI ) CRDNames (cfg * ackgenconfig.Config ) []names.Names {
@@ -380,6 +201,17 @@ func (a *SDKAPI) APIInterfaceTypeName() string {
380
201
return a .API .StructName ()
381
202
}
382
203
204
+ // NewSDKAPI returns a pointer to a new `ackmodel.SDKAPI` struct that describes
205
+ // the AWS SDK API and its respective groupings, mappings and renamings.
206
+ func NewSDKAPI (api * awssdkmodel.API , apiGroupSuffix string ) * SDKAPI {
207
+ return & SDKAPI {
208
+ API : api ,
209
+ APIGroupSuffix : apiGroupSuffix ,
210
+ opMap : nil ,
211
+ typeRenames : nil ,
212
+ }
213
+ }
214
+
383
215
// Override the operation type and/or resource name if specified in config
384
216
func getOpTypeAndResourceName (opID string , cfg * ackgenconfig.Config ) ([]OpType , string ) {
385
217
opType , resName := GetOpTypeAndResourceNameFromOpID (opID , cfg )
@@ -400,3 +232,38 @@ func getOpTypeAndResourceName(opID string, cfg *ackgenconfig.Config) ([]OpType,
400
232
}
401
233
return opTypes , resName
402
234
}
235
+
236
+ // getMemberByPath returns a ShapeRef given a root Shape and a dot-notation
237
+ // object search path. Given the explicit type check for list type members
238
+ // both ".." and "." notations work currently.
239
+ // TODO: Add support for other types such as map.
240
+ func getMemberByPath (
241
+ shape * awssdkmodel.Shape ,
242
+ path string ,
243
+ ) (* awssdkmodel.ShapeRef , bool ) {
244
+ elements := strings .Split (path , "." )
245
+ last := len (elements ) - 1
246
+ for x , elem := range elements {
247
+ if elem == "" {
248
+ continue
249
+ }
250
+ if shape == nil {
251
+ return nil , false
252
+ }
253
+ shapeRef , ok := shape .MemberRefs [elem ]
254
+ if ! ok {
255
+ return nil , false
256
+ }
257
+ if x == last {
258
+ return shapeRef , true
259
+ }
260
+ elemType := shapeRef .Shape .Type
261
+ switch elemType {
262
+ case "list" :
263
+ shape = shapeRef .Shape .MemberRef .Shape
264
+ default :
265
+ shape = shapeRef .Shape
266
+ }
267
+ }
268
+ return nil , false
269
+ }
0 commit comments