Skip to content

Commit b2620bc

Browse files
committed
add support for generic callback hooks
This patch adds support for a generic callback system into the generator config that allows controller implementors to specify some code that should be injected at specific named points in a template. I expect that eventually this generic hook system will be more useful, flexible and extensible than the hodge-podge of custom callback methods and overrides currently in the generator config. Here's an example of a generator config snippet that adds a piece of custom code to be executed in the sdk_update.go.tpl right before the code in the resource manager's `sdkUpdate` method calls the `newUpdateRequestPayload()` function: ```yaml resources: Broker: hooks: sdk_update_pre_build_request: code: if err := rm.requeueIfNotRunning(latest); err != nil { return nil, err } ``` Here is the snippet from the templates/pkg/resource/sdk_update.go.tpl file that shows how we can add these generic named hooks into our templates at various places: ``` {{- if $hookCode := .CRD.HookCode sdk_update_pre_build_request }} {{ $hookCode }} {{ end -}} ``` The controller implementor need only implement the little `requeueIfNotRunning` function, with the function signature described in the generator config code block. We no longer need to have function signatures match for custom callback code since the function signature for callback code is up to the dev writing the generator.yaml config file.
1 parent 4c9aa10 commit b2620bc

File tree

7 files changed

+3496
-1
lines changed

7 files changed

+3496
-1
lines changed

pkg/generate/config/resource.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ type ResourceConfig struct {
2929
// Found and other common error types for primary resources, and thus we
3030
// need these instructions.
3131
Exceptions *ExceptionsConfig `json:"exceptions,omitempty"`
32-
32+
// Hooks is a map, keyed by the hook identifier, of instructions for the
33+
// the code generator about a custom callback hooks that should be injected
34+
// into the resource's manager or SDK binding code.
35+
Hooks map[string]*HooksConfig `json:"hooks"`
3336
// Renames identifies fields in Operations that should be renamed.
3437
Renames *RenamesConfig `json:"renames,omitempty"`
3538
// ListOperation contains instructions for the code generator to generate
@@ -71,6 +74,28 @@ type ResourceConfig struct {
7174
ShortNames []string `json:"shortNames,omitempty"`
7275
}
7376

77+
// HooksConfig instructs the code generator how to inject custom callback hooks
78+
// at various places in the resource manager and SDK linkage code.
79+
//
80+
// Example usage from the AmazonMQ generator config:
81+
//
82+
// resources:
83+
// Broker:
84+
// hooks:
85+
// sdk_update_pre_build_update_request:
86+
// code: |
87+
// if err := rm.requeueIfNotRunning(latest); err != nil {
88+
// return nil, err
89+
// }
90+
//
91+
// Note that the implementor of the AmazonMQ service controller for ACK should
92+
// ensure that there is a `requeueIfNotRunning()` method implementation in
93+
// `pkg/resource/broker`
94+
type HooksConfig struct {
95+
// Code is the Go code to be injected at the hook point
96+
Code string
97+
}
98+
7499
// CompareConfig informs instruct the code generator on how to compare two different
75100
// two objects of the same type
76101
type CompareConfig struct {
@@ -349,3 +374,23 @@ func (c *Config) ResourceShortNames(resourceName string) []string {
349374
}
350375
return rConfig.ShortNames
351376
}
377+
378+
// ResourceHookCode returns a string with custom callback code for a resource
379+
// and hook identifier
380+
func (c *Config) ResourceHookCode(resourceName string, hookID string) string {
381+
if resourceName == "" || hookID == "" {
382+
return ""
383+
}
384+
if c == nil {
385+
return ""
386+
}
387+
rConfig, ok := c.Resources[resourceName]
388+
if !ok {
389+
return ""
390+
}
391+
hook, ok := rConfig.Hooks[hookID]
392+
if !ok {
393+
return ""
394+
}
395+
return hook.Code
396+
}

pkg/generate/mq_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package generate_test
15+
16+
import (
17+
"testing"
18+
19+
"github.com/stretchr/testify/assert"
20+
"github.com/stretchr/testify/require"
21+
22+
"github.com/aws-controllers-k8s/code-generator/pkg/testutil"
23+
)
24+
25+
func TestMQ_HookCode(t *testing.T) {
26+
assert := assert.New(t)
27+
require := require.New(t)
28+
29+
g := testutil.NewGeneratorForService(t, "mq")
30+
31+
crds, err := g.GetCRDs()
32+
require.Nil(err)
33+
34+
crd := getCRDByName("Broker", crds)
35+
require.NotNil(crd)
36+
37+
// The Broker's update operation has a special hook callback configured
38+
expected := `if err := rm.requeueIfNotRunning(latest); err != nil { return nil, err }`
39+
got := crd.HookCode("sdk_update_pre_build_request")
40+
assert.Equal(expected, got)
41+
}

0 commit comments

Comments
 (0)