Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions cmd/ack-generate/command/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.

package command

import (
"fmt"
"io/ioutil"
"path/filepath"
"strings"

"github.com/spf13/cobra"

"github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
ackgenerate "github.com/aws-controllers-k8s/code-generator/pkg/generate/ack"
"github.com/aws-controllers-k8s/code-generator/pkg/model/multiversion"
)

var (
optHubVersion string
optDeprecatedVersions []string
optEnableConversionWebhook bool
)

var webhooksCmd = &cobra.Command{
Use: "webhooks <service>",
Short: "Generates Go files containing conversion, validation and defaulting webhooks.",
RunE: generateWebhooks,
}

func init() {
webhooksCmd.PersistentFlags().StringVar(
&optHubVersion, "hub-version", "", "the hub version for conversion webhooks",
)
webhooksCmd.PersistentFlags().BoolVar(
&optEnableConversionWebhook, "conversion", false, "enable conversion webhooks generation",
)
rootCmd.AddCommand(webhooksCmd)
}

// generateWebhooks generates the Go files for conversion, defaulting and validating webhooks.
func generateWebhooks(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return fmt.Errorf("please specify the service alias for the AWS service API to generate")
}
svcAlias := strings.ToLower(args[0])
if optOutputPath == "" {
optOutputPath = filepath.Join(optServicesDir, svcAlias)
}

apisVersionPath = filepath.Join(optOutputPath, "apis")
files, err := ioutil.ReadDir(apisVersionPath)
if err != nil {
return err
}

apiInfos := map[string]multiversion.APIInfo{}
for _, f := range files {
metadata, err := ack.LoadGenerationMetadata(apisVersionPath, f.Name())
if err != nil {
return err
}
apiInfos[f.Name()] = multiversion.APIInfo{
Status: multiversion.APIStatusUnknown,
AWSSDKVersion: metadata.AWSSDKGoVersion,
GeneratorConfigPath: filepath.Join(apisVersionPath, f.Name(), metadata.GeneratorConfigInfo.OriginalFileName),
}
}

if optHubVersion == "" {
latestAPIVersion, err := getLatestAPIVersion()
if err != nil {
return err
}
optHubVersion = latestAPIVersion
}

mgr, err := multiversion.NewAPIVersionManager(
optCacheDir,
svcAlias,
optHubVersion,
apiInfos,
ack.DefaultConfig,
)
if err != nil {
return err
}

if optEnableConversionWebhook {
ts, err := ackgenerate.ConversionWebhooks(mgr, optTemplateDirs)
if err != nil {
return err
}

if err = ts.Execute(); err != nil {
return err
}

for path, contents := range ts.Executed() {
if optDryRun {
fmt.Printf("============================= %s ======================================\n", path)
fmt.Println(strings.TrimSpace(contents.String()))
continue
}
outPath := filepath.Join(optOutputPath, path)
outDir := filepath.Dir(outPath)
if _, err := ensureDir(outDir); err != nil {
return err
}
if err = ioutil.WriteFile(outPath, contents.Bytes(), 0666); err != nil {
return err
}
}
}
return nil
}
124 changes: 124 additions & 0 deletions pkg/generate/ack/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.

package ack

import (
"fmt"
ttpl "text/template"

"github.com/aws-controllers-k8s/code-generator/pkg/generate/code"
"github.com/aws-controllers-k8s/code-generator/pkg/generate/templateset"
ackmodel "github.com/aws-controllers-k8s/code-generator/pkg/model"
"github.com/aws-controllers-k8s/code-generator/pkg/model/multiversion"
)

var (
webhooksIncludePaths = []string{
"boilerplate.go.tpl",
"apis/webhooks/conversion.go.tpl",
}
webhookCopyPaths = []string{}
webhooksFuncMap = ttpl.FuncMap{
"GoCodeConvert": func(
src *ackmodel.CRD,
dst *ackmodel.CRD,
convertingToHub bool,
hubImportPath string,
sourceVarName string,
targetVarName string,
indentLevel int,
) string {
return code.Convert(src, dst, convertingToHub, hubImportPath, sourceVarName, targetVarName, indentLevel)
},
}
)

// ConversionWebhooks returns a pointer to a TemplateSet containing all the templates
// for generating conversion webhooks.
func ConversionWebhooks(
mgr *multiversion.APIVersionManager,
templateBasePaths []string,
) (*templateset.TemplateSet, error) {
ts := templateset.New(
templateBasePaths,
webhooksIncludePaths,
webhookCopyPaths,
webhooksFuncMap,
)
hubVersion := mgr.GetHubVersion()
hubModel, err := mgr.GetModel(hubVersion)
if err != nil {
return nil, err
}

hubMetaVars := hubModel.MetaVars()
hubCRDs, err := hubModel.GetCRDs()
if err != nil {
return nil, err
}

for _, crd := range hubCRDs {
convertVars := conversionVars{
MetaVars: hubMetaVars,
SourceCRD: crd,
IsHub: true,
}
// Add the hub version template
target := fmt.Sprintf("apis/%s/%s_conversion.go", hubVersion, crd.Names.Snake)
if err = ts.Add(target, "apis/webhooks/conversion.go.tpl", convertVars); err != nil {
return nil, err
}
}

// Add spoke version templates
for _, spokeVersion := range mgr.GetSpokeVersions() {
model, err := mgr.GetModel(spokeVersion)
if err != nil {
return nil, err
}

metaVars := model.MetaVars()
crds, err := model.GetCRDs()
if err != nil {
return nil, err
}

for i, crd := range crds {
convertVars := conversionVars{
MetaVars: metaVars,
SourceCRD: crd,
DestCRD: hubCRDs[i],
IsHub: false,
HubVersion: hubVersion,
}

target := fmt.Sprintf("apis/%s/%s_conversion.go", spokeVersion, crd.Names.Snake)
if err = ts.Add(target, "apis/webhooks/conversion.go.tpl", convertVars); err != nil {
return nil, err
}
}
}

return ts, nil
}

// conversionVars contains template variables for templates that output
// Go conversion functions.
type conversionVars struct {
templateset.MetaVars
SourceCRD *ackmodel.CRD
DestCRD *ackmodel.CRD
HubVersion string
IsHub bool
}
109 changes: 109 additions & 0 deletions pkg/generate/code/convert.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading