Skip to content

Add data plane provisioner prototype #629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
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
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ container: build ## Build the container
@docker -v || (code=$$?; printf "\033[0;31mError\033[0m: there was a problem with Docker\n"; exit $$code)
docker build --build-arg VERSION=$(VERSION) --build-arg GIT_COMMIT=$(GIT_COMMIT) --build-arg DATE=$(DATE) --target $(TARGET) -f build/Dockerfile -t $(PREFIX):$(TAG) .

contaner-provisioner: build-provisioner
docker build --build-arg VERSION=$(VERSION) --build-arg GIT_COMMIT=$(GIT_COMMIT) --build-arg DATE=$(DATE) -f build/ProvisionerDockerfile -t nginx-kubernetes-gateway-provisioner:$(TAG) .

.PHONY: build
build: ## Build the binary
ifeq (${TARGET},local)
@go version || (code=$$?; printf "\033[0;31mError\033[0m: unable to build locally\n"; exit $$code)
CGO_ENABLED=0 GOOS=linux go build -trimpath -a -ldflags "-s -w -X main.version=${VERSION} -X main.commit=${GIT_COMMIT} -X main.date=${DATE}" -o $(OUT_DIR)/gateway github.com/nginxinc/nginx-kubernetes-gateway/cmd/gateway
endif

build-provisioner:
CGO_ENABLED=0 GOOS=linux go build -trimpath -a -ldflags "-s -w -X main.version=${VERSION} -X main.commit=${GIT_COMMIT} -X main.date=${DATE}" -o $(OUT_DIR)/gateway-provisioner github.com/nginxinc/nginx-kubernetes-gateway/cmd/provisioner

.PHONY: generate
generate: ## Run go generate
go generate ./...
Expand Down
5 changes: 5 additions & 0 deletions build/ProvisionerDockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# syntax=docker/dockerfile:1.4
FROM scratch
USER 1001:1001
COPY ./build/.out/gateway-provisioner /usr/bin/
ENTRYPOINT [ "/usr/bin/gateway-provisioner" ]
27 changes: 24 additions & 3 deletions cmd/gateway/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package main
import (
"fmt"
"os"
"strings"

flag "github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/nginxinc/nginx-kubernetes-gateway/internal/config"
Expand Down Expand Up @@ -33,16 +35,35 @@ var (
)

gatewayClassName = flag.String("gatewayclass", "", gatewayClassNameUsage)

gateway = flag.String("gateway", "", "Gateway to watch")

updateGatewayClassStatus = flag.Bool("update-gatewayclass-status", true, "Update GatewayClass status")
)

func main() {
flag.Parse()

var gwNsName types.NamespacedName

if *gateway != "" {
parts := strings.Split(*gateway, "/")
if len(parts) != 2 {
panic("invalid gateway name")
}
gwNsName = types.NamespacedName{
Namespace: parts[0],
Name: parts[1],
}
}

logger := zap.New()
conf := config.Config{
GatewayCtlrName: *gatewayCtlrName,
Logger: logger,
GatewayClassName: *gatewayClassName,
GatewayCtlrName: *gatewayCtlrName,
Logger: logger,
GatewayClassName: *gatewayClassName,
GatewayNsName: &gwNsName,
UpdateGatewayClassStatus: *updateGatewayClassStatus,
}

MustValidateArguments(
Expand Down
82 changes: 82 additions & 0 deletions cmd/provisioner/controllers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"context"
"fmt"

ctlr "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/predicate"

"github.com/nginxinc/nginx-kubernetes-gateway/internal/reconciler"
)

type newReconcilerFunc func(cfg reconciler.Config) *reconciler.Implementation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the gateway and provisioner share this code rather than have the provisioner copy it?


type controllerConfig struct {
namespacedNameFilter reconciler.NamespacedNameFilterFunc
k8sPredicate predicate.Predicate
newReconciler newReconcilerFunc
}

type controllerOption func(*controllerConfig)

func withNamespacedNameFilter(filter reconciler.NamespacedNameFilterFunc) controllerOption {
return func(cfg *controllerConfig) {
cfg.namespacedNameFilter = filter
}
}

func withK8sPredicate(p predicate.Predicate) controllerOption {
return func(cfg *controllerConfig) {
cfg.k8sPredicate = p
}
}

// withNewReconciler allows us to mock reconciler creation in the unit tests.
func withNewReconciler(newReconciler newReconcilerFunc) controllerOption {
return func(cfg *controllerConfig) {
cfg.newReconciler = newReconciler
}
}

func defaultControllerConfig() controllerConfig {
return controllerConfig{
newReconciler: reconciler.NewImplementation,
}
}

func registerController(
ctx context.Context,
objectType client.Object,
mgr manager.Manager,
eventCh chan<- interface{},
options ...controllerOption,
) error {
cfg := defaultControllerConfig()

for _, opt := range options {
opt(&cfg)
}

builder := ctlr.NewControllerManagedBy(mgr).For(objectType)

if cfg.k8sPredicate != nil {
builder = builder.WithEventFilter(cfg.k8sPredicate)
}

recCfg := reconciler.Config{
Getter: mgr.GetClient(),
ObjectType: objectType,
EventCh: eventCh,
NamespacedNameFilter: cfg.namespacedNameFilter,
}

err := builder.Complete(cfg.newReconciler(recCfg))
if err != nil {
return fmt.Errorf("cannot build a controller for %T: %w", objectType, err)
}

return nil
}
Loading