Skip to content

Commit

Permalink
feat: simplify controller register step
Browse files Browse the repository at this point in the history
  • Loading branch information
yuwenma committed Jan 7, 2025
1 parent 974a6ea commit 5d6c35d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package generatecontroller

import (
"context"
"errors"
"fmt"
"strings"

Expand Down Expand Up @@ -96,5 +97,10 @@ func RunController(ctx context.Context, o *GenerateControllerOptions) error {
ProtoResource: o.ProtoName,
ProtoVersion: version,
}
return scaffold.Scaffold(serviceName, o.ProtoName, cArgs)
err1 := scaffold.GenerateController(serviceName, o.ProtoName, cArgs)
err2 := scaffold.RegisterController(serviceName, o.ProtoName)
if err1 != nil || err2 != nil {
return errors.Join(err1, err2)
}
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ func RunGenerateBasicReconciler(ctx context.Context, o *GenerateBasicReconcilerO
OutputMapperDirectory: o.OutputMapperDirectory,
}
if err := generatemapper.RunGenerateMapper(ctx, mapperOps); err != nil {
return fmt.Errorf("generate types: %w", err)
return fmt.Errorf("generate mapper: %w", err)
}
controllerOps := &generatecontroller.GenerateControllerOptions{
GenerateOptions: o.GenerateOptions,
Kind: o.Kind,
ProtoName: o.ProtoName,
}
if err := generatecontroller.RunController(ctx, controllerOps); err != nil {
return fmt.Errorf("generate types: %w", err)
return fmt.Errorf("generate controller: %w", err)
}
return nil
}
80 changes: 60 additions & 20 deletions dev/tools/controllerbuilder/scaffold/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ import (
"bytes"
"errors"
"fmt"
"io/fs"
"go/format"
"go/parser"
"go/token"
"os"
"path/filepath"
"runtime/debug"
"strings"
"text/template"

ccTemplate "github.com/GoogleCloudPlatform/k8s-config-connector/dev/tools/controllerbuilder/template/controller"
"github.com/fatih/color"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/imports"
)

Expand All @@ -38,14 +42,47 @@ var funcMap = template.FuncMap{
"ToLower": strings.ToLower,
}

func Scaffold(service, kind string, cArgs *ccTemplate.ControllerArgs) error {
if err := generateController(service, kind, cArgs); err != nil {
func RegisterController(service, kind string) error {
// Read register file
directControllerPkgPath, err := buildDirectControllerPath()
if err != nil {
return nil
}
registerFilePath := filepath.Join(directControllerPkgPath, "register", "register.go")
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, registerFilePath, nil, parser.ParseComments)
if err != nil {
return err
}

// Get main model name
bi, ok := debug.ReadBuildInfo()
if !ok {
return fmt.Errorf("could not read build info")
}
modelPath := strings.TrimSuffix(bi.Main.Path, currRelPath)

importPath := filepath.Join(modelPath, directControllerRelPath, service)
added := astutil.AddNamedImport(fset, f, "_", importPath)
if !added {
fmt.Printf("skip registering controller %s\n", service)
return nil
}

out := &bytes.Buffer{}
err = format.Node(out, fset, f)
if err != nil {
return fmt.Errorf("error formatting code: %w", err)
}

if err := FormatImports(registerFilePath, out.Bytes()); err != nil {
return err
}
color.HiGreen("New controller %s has been registered.\n", kind)
return nil
}

func generateController(service, kind string, cArgs *ccTemplate.ControllerArgs) error {
func GenerateController(service, kind string, cArgs *ccTemplate.ControllerArgs) error {
tmpl, err := template.New(cArgs.Kind).Funcs(funcMap).Parse(ccTemplate.ControllerTemplate)
if err != nil {
return fmt.Errorf("parse controller template: %w", err)
Expand All @@ -60,6 +97,12 @@ func generateController(service, kind string, cArgs *ccTemplate.ControllerArgs)
if err != nil {
return err
}
if _, err := os.Stat(controllerFilePath); err == nil {
fmt.Printf("file %s already exists, skipping\n", controllerFilePath)
return nil
} else if !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("unexpected controller file: %w", err)
}

// Write the generated controller.go to pkg/controller/direct/<service>/<resource>_controller.go
if err := WriteToFile(controllerFilePath, controllerOutput.Bytes()); err != nil {
Expand All @@ -69,11 +112,11 @@ func generateController(service, kind string, cArgs *ccTemplate.ControllerArgs)
if err := FormatImports(controllerFilePath, controllerOutput.Bytes()); err != nil {
return err
}
color.HiGreen("New controller %s has been generated. \nEnjoy it!\n", kind)
color.HiGreen("New controller %s has been generated.", kind)
return nil
}

func buildResourcePath(service, filename string) (string, error) {
func buildDirectControllerPath() (string, error) {
pwd, err := os.Getwd()
if err != nil {
return "", fmt.Errorf("get current working directory: %w", err)
Expand All @@ -83,24 +126,21 @@ func buildResourcePath(service, filename string) (string, error) {
return "", fmt.Errorf("get absolute path %s: %w", pwd, err)
}
seg := strings.Split(abs, currRelPath)
controllerDir := filepath.Join(seg[0], directControllerRelPath, service)
return filepath.Join(seg[0], directControllerRelPath), nil
}

func buildControllerPath(service, protoResource string) (string, error) {
filename := strings.ToLower(protoResource) + "_controller.go"
directControllerPkgPath, err := buildDirectControllerPath()
if err != nil {
return "", nil
}
controllerDir := filepath.Join(directControllerPkgPath, service)
err = os.MkdirAll(controllerDir, os.ModePerm)
if err != nil {
return "", fmt.Errorf("create controller directory %s: %w", controllerDir, err)
}
resourceFilePath := filepath.Join(controllerDir, filename)
if _, err = os.Stat(resourceFilePath); err != nil {
if !errors.Is(err, fs.ErrNotExist) {
return "", fmt.Errorf("could not stat path %s: %w", resourceFilePath, err)
}
// otherwise create the file
return resourceFilePath, nil
}
return "", fmt.Errorf("file %s already exist", resourceFilePath)
}

func buildControllerPath(service, protoResource string) (string, error) {
return buildResourcePath(service, strings.ToLower(protoResource)+"_controller.go")
return filepath.Join(controllerDir, filename), nil
}

func FormatImports(path string, out []byte) error {
Expand Down
8 changes: 1 addition & 7 deletions docs/develop-resources/deep-dives/4-add-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,7 @@ if there is no previous reference method, You may need to add a new` Resolve<Ref

Check to make sure your validation is complete.


## 4.3 Register your controller

To wire your controller in the Config Connector operator, you need to [register the controller](https://github.com/GoogleCloudPlatform/k8s-config-connector/blob/master/pkg/controller/direct/register/register.go)


## 4.4 Verify your controller
## 4.3 Verify your controller

To turn on the SciFi controller to reconcile resources:

Expand Down

0 comments on commit 5d6c35d

Please sign in to comment.