Skip to content

Commit

Permalink
Merge branch 'main' into feat/show-runners
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalgalaw committed Nov 30, 2023
2 parents 9a5ba57 + e7b3bc8 commit 2f8ab83
Show file tree
Hide file tree
Showing 17 changed files with 537 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

- uses: actions/setup-go@v4
with:
go-version: '1.21.3'
go-version: '1.21.4'

- name: make verify
run: make verify
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/foss.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Go 1.x
uses: actions/setup-go@v4
with:
go-version: '1.21.3'
go-version: '1.21.4'
id: go

- name: Checkout code
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- run: git fetch --force --tags
- uses: actions/setup-go@v4
with:
go-version: '1.21.3'
go-version: '1.21.4'

- name: Synopsys Detect
run: |
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ Issue-related communication should happen within the concerned issue.

## Contributions

Contributions are highly welcome.

If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request.

When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible.

If you are new to contributing in GitHub, [First Contributions](https://github.com/firstcontributions/first-contributions) might be a good starting point.

Before you can contribute, you will need to sign our CLA and send the signed CLA to CLA[email protected].
Before you can contribute, you will need to sign our Contributor License Agreement (CLA). When you create your first pull request, you will be requested by our CLA-assistant to sign this CLA.

### Semantic Commit Messages

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: MIT
# Build the manager binary
FROM golang:1.21.3 as builder
FROM golang:1.21.4 as builder
ARG TARGETOS
ARG TARGETARCH

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ export GARM_OPERATOR_VERSION=<garm-operator-version>
export GARM_SERVER_URL=<garm-server-url>
export GARM_SERVER_USERNAME=<garm-server-username>
export GARM_SERVER_PASSWORD=<garm-server-password>
export OPERATOR_WATCH_NAMESPACE=<operator-watch-namespace>
curl -L https://github.com/mercedes-benz/garm-operator/releases/download/${GARM_OPERATOR_VERSION}/garm-operator-all.yaml | envsubst | kubectl apply -f -
```

The full configuration parsing documentation can be found in the [configuration parsing guide](./docs/config/configuration-parsing.md)

#### Custom Resources

The CRD documentation can be also seen via [docs.crds.dev](https://doc.crds.dev/github.com/mercedes-benz/garm-operator).
Expand Down
175 changes: 54 additions & 121 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ package main

import (
"context"
"errors"
"flag"
"fmt"
"os"
"time"

"github.com/spf13/pflag"
"gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/klog/v2"
"k8s.io/klog/v2/klogr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
Expand All @@ -23,7 +20,8 @@ import (

garmoperatorv1alpha1 "github.com/mercedes-benz/garm-operator/api/v1alpha1"
"github.com/mercedes-benz/garm-operator/internal/controller"
"github.com/mercedes-benz/garm-operator/pkg/client"
"github.com/mercedes-benz/garm-operator/pkg/config"
"github.com/mercedes-benz/garm-operator/pkg/flags"
)

var (
Expand All @@ -39,71 +37,45 @@ func init() {
}

func main() {
var (
metricsAddr string
enableLeaderElection bool
probeAddr string
syncPeriod time.Duration

watchNamespace string

garmServer string
garmUsername string
garmPassword string
)

exitCode := 0
defer func() { os.Exit(exitCode) }()

flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.DurationVar(&syncPeriod, "sync-period", 5*time.Minute,
"The minimum interval at which watched resources are reconciled (e.g. 15m)")

flag.StringVar(&watchNamespace, "namespace", "",
"Namespace that the controller watches to reconcile garm objects. If unspecified, the controller watches for garm objects across all namespaces.")

flag.StringVar(&garmServer, "garm-server", "", "The address of the GARM server")
flag.StringVar(&garmUsername, "garm-username", "", "The username for the GARM server")
flag.StringVar(&garmPassword, "garm-password", "", "The password for the GARM server")

klog.InitFlags(flag.CommandLine)
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()
ctrl.SetLogger(klogr.New())

// configure garm client from environment variables
if len(os.Getenv("GARM_SERVER")) > 0 {
setupLog.Info("Using garm-server from environment variable")
garmServer = os.Getenv("GARM_SERVER")
}
if len(os.Getenv("GARM_USERNAME")) > 0 {
setupLog.Info("Using garm-username from environment variable")
garmUsername = os.Getenv("GARM_USERNAME")
}
if len(os.Getenv("GARM_PASSWORD")) > 0 {
setupLog.Info("Using garm-password from environment variable")
garmPassword = os.Getenv("GARM_PASSWORD")
// initiate flags
f := flags.InitiateFlags()

// retrieve config flag value for GenerateConfig() function
configFile := f.Lookup("config").Value.String()

// call GenerateConfig() function from config package
if err := config.GenerateConfig(f, configFile); err != nil {
setupLog.Error(err, "failed to read config")
os.Exit(1)
}
if len(os.Getenv("WATCH_NAMESPACE")) > 0 {
setupLog.Info("using watch-namespace from environment variable")
watchNamespace = os.Getenv("WATCH_NAMESPACE")

// check if dry-run flag is set to true
dryRun, _ := f.GetBool("dry-run")

// perform dry-run if enabled and print out the generated Config as yaml
if dryRun {
yamlConfig, err := yaml.Marshal(config.Config)
if err != nil {
setupLog.Error(err, "failed to marshal config as yaml")
os.Exit(1)
}
fmt.Printf("generated Config as yaml:\n%s\n", yamlConfig)
os.Exit(0)
}

var watchNamespaces []string
if watchNamespace != "" {
watchNamespaces = []string{watchNamespace}
if config.Config.Operator.WatchNamespace != "" {
watchNamespaces = []string{config.Config.Operator.WatchNamespace}
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
MetricsBindAddress: config.Config.Operator.MetricsBindAddress,
Port: 9443,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
HealthProbeBindAddress: config.Config.Operator.HealthProbeBindAddress,
LeaderElection: config.Config.Operator.LeaderElection,
LeaderElectionID: "b608d8b3.mercedes-benz.com",
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
Expand All @@ -119,78 +91,45 @@ func main() {
//
// Default Sync Period = 10 hours.
// Set default via flag to 5 minutes
SyncPeriod: &syncPeriod,
SyncPeriod: &config.Config.Operator.SyncPeriod,
Cache: cache.Options{
Namespaces: watchNamespaces,
SyncPeriod: &syncPeriod,
SyncPeriod: &config.Config.Operator.SyncPeriod,
},
})
if err != nil {
setupLog.Error(err, "unable to start manager")
exitCode = 1
return
}

if garmServer == "" {
setupLog.Error(errors.New("unable to fetch garm server from either flag or os_env"), "unable to start manager")
exitCode = 1
return
}
if garmUsername == "" {
setupLog.Error(errors.New("unable to fetch garm username from either flag or os_env"), "unable to start manager")
exitCode = 1
return
}
if garmPassword == "" {
setupLog.Error(errors.New("unable to fetch garm password from either flag or os_env"), "unable to start manager")
exitCode = 1
return
os.Exit(1)
}

// need central cache, where all clients get token from...
garmClient := client.New(&client.GarmScopeParams{
BaseURL: garmServer,
Username: garmUsername,
Password: garmPassword,
Debug: false,
})
garmClient.Login()

if err = (&controller.EnterpriseReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("enterprise-controller"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Enterprise")
exitCode = 1
return
os.Exit(1)
}
if err = (&controller.PoolReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("pool-controller"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Pool")
exitCode = 1
return
os.Exit(1)
}

if os.Getenv("CREATE_WEBHOOK") == "true" {
if err = (&garmoperatorv1alpha1.Pool{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "Pool")
exitCode = 1
return
}
if err = (&garmoperatorv1alpha1.Image{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "Image")
exitCode = 1
return
}
if err = (&garmoperatorv1alpha1.Repository{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "Repository")
exitCode = 1
return
}
if err = (&garmoperatorv1alpha1.Pool{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "Pool")
os.Exit(1)
}
if err = (&garmoperatorv1alpha1.Image{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "Image")
os.Exit(1)
}
if err = (&garmoperatorv1alpha1.Repository{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create webhook", "webhook", "Repository")
os.Exit(1)
}

if err = (&controller.OrganizationReconciler{
Expand All @@ -199,8 +138,7 @@ func main() {
Recorder: mgr.GetEventRecorderFor("organization-controller"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Organization")
exitCode = 1
return
os.Exit(1)
}

if err = (&controller.RepositoryReconciler{
Expand All @@ -209,8 +147,7 @@ func main() {
Recorder: mgr.GetEventRecorderFor("repository-controller"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Repository")
exitCode = 1
return
os.Exit(1)
}

eventChan := make(chan event.GenericEvent)
Expand All @@ -222,8 +159,7 @@ func main() {
// setup controller so it can reconcile if events from eventChan are queued
if err = runnerReconciler.SetupWithManager(mgr, eventChan); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Runner")
exitCode = 1
return
os.Exit(1)
}

// fetch runner instances periodically and enqueue reconcile events for runner ctrl if external system has changed
Expand All @@ -235,19 +171,16 @@ func main() {

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
exitCode = 1
return
os.Exit(1)

Check failure on line 174 in cmd/main.go

View workflow job for this annotation

GitHub Actions / lint and test

exitAfterDefer: os.Exit will exit, and `defer cancel()` will not run (gocritic)
}
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up ready check")
exitCode = 1
return
os.Exit(1)
}

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
exitCode = 1
return
os.Exit(1)
}
}
8 changes: 1 addition & 7 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,8 @@ spec:
- --garm-server=$GARM_SERVER_URL
- --garm-username=$GARM_SERVER_USERNAME
- --garm-password=$GARM_SERVER_PASSWORD
- --operator-watch-namespace=$OPERATOR_WATCH_NAMESPACE
image: controller:latest
env:
- name: CREATE_WEBHOOK
value: "true"
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
name: manager
securityContext:
allowPrivilegeEscalation: false
Expand Down
Loading

0 comments on commit 2f8ab83

Please sign in to comment.