Skip to content

Commit 4e0e553

Browse files
Add CRD method to get OutputShape (#92)
Issue #, if available: Description of changes: This PR also adds a method `GetOutputShape` to crd which provides output shape For example, `CreateReplicationGroupOutput`, `ModifyReplicationGroupOutput` wrap `ReplicationGroup` object. This method is useful in creating reusable code which populates the fields from wrapped object to `ko`. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 85436ab commit 4e0e553

File tree

3 files changed

+78
-36
lines changed

3 files changed

+78
-36
lines changed

pkg/generate/code/set_resource.go

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func SetResource(
125125
// Use the wrapper field path if it's given in the ack-generate config file.
126126
wrapperFieldPath := r.GetOutputWrapperFieldPath(op)
127127
if wrapperFieldPath != nil {
128-
outputShape, err = GetWrapperOutputShape(outputShape, *wrapperFieldPath)
128+
outputShape, err = r.GetWrapperOutputShape(outputShape, *wrapperFieldPath)
129129
if err != nil {
130130
msg := fmt.Sprintf("Unable to unwrap the output shape: %v", err)
131131
panic(msg)
@@ -317,40 +317,6 @@ func SetResource(
317317
return out
318318
}
319319

320-
// GetWrapperOutputShape returns the shape of the last element of a given field
321-
// Path. It carefully unwraps the output shape and verifies that every element
322-
// of the field path exists in their correspanding parent shape and that they are
323-
// structures.
324-
func GetWrapperOutputShape(
325-
shape *awssdkmodel.Shape,
326-
fieldPath string,
327-
) (*awssdkmodel.Shape, error) {
328-
if fieldPath == "" {
329-
return shape, nil
330-
}
331-
fieldPathParts := strings.Split(fieldPath, ".")
332-
for x, wrapperField := range fieldPathParts {
333-
for memberName, memberRef := range shape.MemberRefs {
334-
if memberName == wrapperField {
335-
if memberRef.Shape.Type != "structure" {
336-
// All the mentionned shapes must be structure
337-
return nil, fmt.Errorf(
338-
"Expected SetOutput.WrapperFieldPath to only contain fields of type 'structure'."+
339-
" Found %s of type '%s'",
340-
memberName, memberRef.Shape.Type,
341-
)
342-
}
343-
remainPath := strings.Join(fieldPathParts[x+1:], ".")
344-
return GetWrapperOutputShape(memberRef.Shape, remainPath)
345-
}
346-
}
347-
return nil, fmt.Errorf(
348-
"Incorrect SetOutput.WrapperFieldPath. Could not find %s in Shape %s",
349-
wrapperField, shape.ShapeName,
350-
)
351-
}
352-
return shape, nil
353-
}
354320

355321
func ListMemberNameInReadManyOutput(
356322
r *model.CRD,

pkg/generate/code/set_resource_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2636,7 +2636,7 @@ func TestGetWrapperOutputShape(t *testing.T) {
26362636
}
26372637
for _, tt := range tests {
26382638
t.Run(tt.name, func(t *testing.T) {
2639-
outputShape, err := code.GetWrapperOutputShape(tt.args.outputShape, tt.args.fieldPath)
2639+
outputShape, err := crd.GetWrapperOutputShape(tt.args.outputShape, tt.args.fieldPath)
26402640
if (err != nil) != tt.wantErr {
26412641
assert.Fail(fmt.Sprintf("GetWrapperOutputShape() error = %v, wantErr %v", err, tt.wantErr))
26422642
} else if !tt.wantErr {

pkg/model/crd.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package model
1515

1616
import (
17+
"errors"
1718
"fmt"
1819
"sort"
1920
"strings"
@@ -400,6 +401,81 @@ func (r *CRD) GetOutputWrapperFieldPath(
400401
return &opConfig.OutputWrapperFieldPath
401402
}
402403

404+
// GetOutputShape returns the Output shape for given operation.
405+
func (r *CRD) GetOutputShape(
406+
// The operation to look for the Output shape
407+
op *awssdkmodel.Operation,
408+
) (*awssdkmodel.Shape, error) {
409+
if op == nil {
410+
return nil, errors.New("no output shape for nil operation")
411+
}
412+
413+
outputShape := op.OutputRef.Shape
414+
if outputShape == nil {
415+
return nil, errors.New("output shape not found")
416+
}
417+
418+
// We might be in a "wrapper" shape. Unwrap it to find the real object
419+
// representation for the CRD's createOp/DescribeOP.
420+
421+
// Use the wrapper field path if it's given in the ack-generate config file.
422+
wrapperFieldPath := r.GetOutputWrapperFieldPath(op)
423+
if wrapperFieldPath != nil {
424+
wrapperOutputShape, err := r.GetWrapperOutputShape(outputShape, *wrapperFieldPath)
425+
if err != nil {
426+
return nil, fmt.Errorf("unable to unwrap the output shape: %v", err)
427+
}
428+
outputShape = wrapperOutputShape
429+
} else {
430+
// If the wrapper field path is not specified in the config file and if
431+
// there is a single member shape and that member shape is a structure,
432+
// unwrap it.
433+
if outputShape.UsedAsOutput && len(outputShape.MemberRefs) == 1 {
434+
for _, memberRef := range outputShape.MemberRefs {
435+
if memberRef.Shape.Type == "structure" {
436+
outputShape = memberRef.Shape
437+
}
438+
}
439+
}
440+
}
441+
return outputShape, nil
442+
}
443+
444+
// GetWrapperOutputShape returns the shape of the last element of a given field
445+
// Path. It carefully unwraps the output shape and verifies that every element
446+
// of the field path exists in their correspanding parent shape and that they are
447+
// structures.
448+
func (r *CRD) GetWrapperOutputShape(
449+
shape *awssdkmodel.Shape,
450+
fieldPath string,
451+
) (*awssdkmodel.Shape, error) {
452+
if fieldPath == "" {
453+
return shape, nil
454+
}
455+
fieldPathParts := strings.Split(fieldPath, ".")
456+
for x, wrapperField := range fieldPathParts {
457+
for memberName, memberRef := range shape.MemberRefs {
458+
if memberName == wrapperField {
459+
if memberRef.Shape.Type != "structure" {
460+
// All the mentionned shapes must be structure
461+
return nil, fmt.Errorf(
462+
"Expected SetOutput.WrapperFieldPath to only contain fields of type 'structure'."+
463+
" Found %s of type '%s'",
464+
memberName, memberRef.Shape.Type,
465+
)
466+
}
467+
remainPath := strings.Join(fieldPathParts[x+1:], ".")
468+
return r.GetWrapperOutputShape(memberRef.Shape, remainPath)
469+
}
470+
}
471+
return nil, fmt.Errorf(
472+
"Incorrect SetOutput.WrapperFieldPath. Could not find %s in Shape %s",
473+
wrapperField, shape.ShapeName,
474+
)
475+
}
476+
return shape, nil
477+
}
478+
403479
// GetCustomImplementation returns custom implementation method name for the
404480
// supplied operation as specified in generator config
405481
func (r *CRD) GetCustomImplementation(

0 commit comments

Comments
 (0)