Skip to content

Commit

Permalink
Initial v1alpha2 Workflow controller
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Doherty <[email protected]>
  • Loading branch information
chrisdoherty4 committed Feb 28, 2024
1 parent 0c87805 commit 8a89f80
Show file tree
Hide file tree
Showing 43 changed files with 1,033 additions and 166 deletions.
3 changes: 2 additions & 1 deletion .yamllint
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
extends: default

rules:
Expand All @@ -14,6 +13,8 @@ rules:
max: 160
allow-non-breakable-inline-mappings: true
truthy: disable
indentation:
indent-sequences: whatever

ignore: |
out
24 changes: 14 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ help: ## Print this help
VERSION ?= $(shell git rev-parse --short HEAD)

# Define all the binaries we build for this project that get packaged into containers.
BINARIES := tink-server tink-agent tink-worker tink-controller virtual-worker
BINARIES := tink-server tink-agent tink-worker tink-controller tink-controller-v1alpha2 virtual-worker

.PHONY: build
build: $(BINARIES) ## Build all tink binaries. Cross build by setting GOOS and GOARCH.
Expand Down Expand Up @@ -97,37 +97,41 @@ generate-proto: buf.gen.yaml buf.lock $(shell git ls-files '**/*.proto') $(BUF)
$(GOFUMPT) -w internal/proto/workflow/v2/*.pb.*

.PHONY: generate
generate: generate-proto generate-go generate-manifests ## Generate code, manifests etc.
generate: ## Generate code, manifests etc.
generate: generate-proto generate-go generate-manifests

.PHONY: generate-go
generate-go: $(CONTROLLER_GEN) $(GOFUMPT)
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate/boilerplate.generatego.txt" paths="./api/..."
$(GOFUMPT) -w ./api

.PHONY: generate-manifests
generate-manifests: generate-crds generate-rbacs generate-server-rbacs ## Generate manifests e.g. CRD, RBAC etc.
generate-manifests: ## Generate manifests e.g. CRD, RBAC etc.
generate-manifests: generate-crds generate-rbac

.PHONY: generate-crds
generate-crds: $(CONTROLLER_GEN) $(YAMLFMT)
$(CONTROLLER_GEN) \
paths=./api/... \
crd:crdVersions=v1 \
rbac:roleName=manager-role \
output:crd:dir=./config/crd/bases \
output:webhook:dir=./config/webhook \
webhook
$(YAMLFMT) ./config/crd/bases/* ./config/webhook/*

.PHONY: generate-rbacs
generate-rbacs: $(CONTROLLER_GEN) $(YAMLFMT)
.PHONY: generate-rbac
generate-rbac: $(CONTROLLER_GEN) $(YAMLFMT)

.PHONY: generate-controller-rbac
generate-manager-rbac:
$(CONTROLLER_GEN) \
paths=./internal/controller/... \
output:rbac:dir=./config/rbac/ \
paths=./internal/workflow/... \
output:rbac:dir=./config/manager-rbac/ \
rbac:roleName=manager-role
$(YAMLFMT) ./config/rbac/*

.PHONY: generate-server-rbacs
generate-server-rbacs: $(CONTROLLER_GEN) $(YAMLFMT)
.PHONY: generate-server-rbac
generate-server-rbac: $(CONTROLLER_GEN) $(YAMLFMT)
$(CONTROLLER_GEN) \
paths=./internal/server/... \
output:rbac:dir=./config/server-rbac \
Expand Down
2 changes: 1 addition & 1 deletion Tools.mk
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ PROTOC_GEN_GO_GRPC := $(TOOLS_DIR)/protoc-gen-go-grpc
PROTOC_GEN_GO_VER := v1.28
PROTOC_GEN_GO := $(TOOLS_DIR)/protoc-gen-go

CONTROLLER_GEN_VER := v0.11
CONTROLLER_GEN_VER := v0.14
CONTROLLER_GEN := $(TOOLS_DIR)/controller-gen-$(CONTROLLER_GEN_VER)

KUSTOMIZE_VER := v4.5
Expand Down
1 change: 0 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

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

2 changes: 1 addition & 1 deletion api/v1alpha2/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Condition struct {
Status ConditionStatus `json:"status"`

// LastTransition is the last time the condition transitioned from one status to another.
LastTransition *metav1.Time `json:"lastTransitionTime"`
LastTransition metav1.Time `json:"lastTransitionTime"`

// Reason is a short CamelCase description for the conditions last transition.
// +optional
Expand Down
4 changes: 3 additions & 1 deletion api/v1alpha2/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ type WorkflowStatus struct {

// StartedAt is the time the first action was requested. Nil indicates the Workflow has not
// started.
// +optional
StartedAt *metav1.Time `json:"startedAt,omitempty"`

// LastTransition is the observed time when State transitioned last.
LastTransition *metav1.Time `json:"lastTransitioned,omitempty"`
LastTransition metav1.Time `json:"lastTransitioned,omitempty"`

// State describes the current state of the Workflow.
State WorkflowState `json:"state,omitempty"`

// Conditions details a set of observations about the Workflow.
// +optional
Conditions Conditions `json:"conditions"`
}

Expand Down
11 changes: 2 additions & 9 deletions api/v1alpha2/zz_generated.deepcopy.go

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

2 changes: 1 addition & 1 deletion buf.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ deps:
- remote: buf.build
owner: googleapis
repository: googleapis
commit: e874a0be2bf140a5a4c7d4122c635823
commit: 7e6f6e774e29406da95bd61cdcdbc8bc
10 changes: 10 additions & 0 deletions cmd/tink-controller-v1alpha2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM alpine:3.15

ARG TARGETOS
ARG TARGETARCH

RUN apk add --no-cache --update --upgrade ca-certificates

COPY bin/tink-controller-v1alpha2-${TARGETOS}-${TARGETARCH} /usr/bin/tink-controller

ENTRYPOINT ["/usr/bin/tink-controller"]
179 changes: 179 additions & 0 deletions cmd/tink-controller-v1alpha2/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package main

import (
"fmt"
"os"
"strings"

"github.com/go-logr/logr"
"github.com/go-logr/zapr"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
tinkv1 "github.com/tinkerbell/tink/api/v1alpha2"
"github.com/tinkerbell/tink/internal/workflow"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/runtime"
amruntimeutil "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/metrics/server"
)

// version is set at build time.
var version = "devel"

// scheme is passed to the manager.
var scheme = runtime.NewScheme()

func init() {
amruntimeutil.Must(tinkv1.AddToScheme(scheme))

//+kubebuilder:scaffold:scheme
}

type Config struct {
K8sAPI string
Kubeconfig string // only applies to out of cluster
MetricsAddr string
ProbeAddr string
EnableLeaderElection bool
}

func (c *Config) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&c.K8sAPI, "kubernetes", "",
"The Kubernetes API URL, used for in-cluster client construction.")
fs.StringVar(&c.Kubeconfig, "kubeconfig", "", "Absolute path to the kubeconfig file")
fs.StringVar(&c.MetricsAddr, "metrics-bind-address", ":8080",
"The address the metric endpoint binds to.")
fs.StringVar(&c.ProbeAddr, "health-probe-bind-address", ":8081",
"The address the probe endpoint binds to.")
fs.BoolVar(&c.EnableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
}

func main() {
cmd := NewRootCommand()
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
}

func NewRootCommand() *cobra.Command {
var config Config

zlog, err := zap.NewProduction()
if err != nil {
panic(err)
}
logger := zapr.NewLogger(zlog).WithName("github.com/tinkerbell/tink")

cmd := &cobra.Command{
Use: "tink-controller",
PreRunE: func(cmd *cobra.Command, args []string) error {
viper, err := createViper(logger)
if err != nil {
return fmt.Errorf("config init: %w", err)
}
return applyViper(viper, cmd)
},
RunE: func(cmd *cobra.Command, args []string) error {
logger.Info("Starting controller version " + version)

ccfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: config.Kubeconfig},
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: config.K8sAPI}})

cfg, err := ccfg.ClientConfig()
if err != nil {
return err
}

namespace, _, err := ccfg.Namespace()
if err != nil {
return err
}

opts := ctrl.Options{
Logger: logger,
LeaderElection: config.EnableLeaderElection,
LeaderElectionID: "tink.tinkerbell.org",
LeaderElectionNamespace: namespace,
Metrics: server.Options{
BindAddress: config.MetricsAddr,
},
HealthProbeBindAddress: config.ProbeAddr,
Scheme: scheme,
}

mgr, err := ctrl.NewManager(cfg, opts)
if err != nil {
return err
}

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
return err
}

if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
return err
}

if err := workflow.NewReconciler(mgr.GetClient()).SetupWithManager(mgr); err != nil {
return err
}

return mgr.Start(cmd.Context())
},
}
config.AddFlags(cmd.Flags())
return cmd
}

func createViper(logger logr.Logger) (*viper.Viper, error) {
v := viper.New()
v.AutomaticEnv()
v.SetConfigName("tink-controller")
v.AddConfigPath("/etc/tinkerbell")
v.AddConfigPath(".")
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))

// If a config file is found, read it in.
if err := v.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return nil, fmt.Errorf("loading config file: %w", err)
}
logger.Info("no config file found")
} else {
logger.Info("loaded config file", "configFile", v.ConfigFileUsed())
}

return v, nil
}

func applyViper(v *viper.Viper, cmd *cobra.Command) error {
errors := []error{}

cmd.Flags().VisitAll(func(f *pflag.Flag) {
if !f.Changed && v.IsSet(f.Name) {
val := v.Get(f.Name)
if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil {
errors = append(errors, err)
return
}
}
})

if len(errors) > 0 {
errs := []string{}
for _, err := range errors {
errs = append(errs, err.Error())
}
return fmt.Errorf(strings.Join(errs, ", "))
}

return nil
}
2 changes: 1 addition & 1 deletion cmd/tink-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/tinkerbell/tink/internal/controller"
"github.com/tinkerbell/tink/internal/deprecated/controller"
"go.uber.org/zap"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
Expand Down
Loading

0 comments on commit 8a89f80

Please sign in to comment.