Skip to content

Commit

Permalink
feat: add initialization of garm instance
Browse files Browse the repository at this point in the history
  • Loading branch information
H777K committed Nov 29, 2023
1 parent ad14380 commit 64817f7
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 1 deletion.
18 changes: 17 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ 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"
)
Expand Down Expand Up @@ -100,6 +101,21 @@ func main() {
os.Exit(1)
}

ctx := ctrl.SetupSignalHandler()

if config.Config.Garm.Init {
initClient := client.NewInitClient()
if err = initClient.Init(ctx, client.GarmScopeParams{
BaseURL: config.Config.Garm.Server,
Username: config.Config.Garm.Username,
Password: config.Config.Garm.Password,
Email: config.Config.Garm.Email,
}); err != nil {
setupLog.Error(err, "failed to initialize GARM")
os.Exit(1)
}
}

if err = (&controller.EnterpriseReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Expand Down Expand Up @@ -175,7 +191,7 @@ func main() {
}

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
if err := mgr.Start(ctx); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
Expand Down
8 changes: 8 additions & 0 deletions docs/config/configuration-parsing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ All ENVs with the `OPERATOR_` and `GARM_` prefix will be merged by koanf. Howeve
GARM_SERVER
GARM_USERNAME
GARM_PASSWORD
GARM_INIT
GARM_EMAIL
OPERATOR_METRICS_BIND_ADDRESS
OPERATOR_HEALTH_PROBE_BIND_ADDRESS
Expand All @@ -53,6 +55,8 @@ The following flags will be parsed and can be found in the [flags package](../..
--garm-server
--garm-username
--garm-password
--garm-init
--garm-email
--operator-metrics-bind-address
--operator-health-probe-bind-address
Expand Down Expand Up @@ -80,6 +84,8 @@ garm:
server: http://garm-server:9997
username: admin
password: 123456789
init: false
email: ""
operator:
metricsbindaddress: :8080
healthprobebindaddress: :8081
Expand All @@ -98,6 +104,8 @@ garm:
server: "http://garm-server:9997"
username: "garm-username"
password: "garm-password"
init: false
email: ""

operator:
metrics_bind_address: ":7000"
Expand Down
46 changes: 46 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
package client

import (
"context"
"errors"
"fmt"
"net/url"
"strings"

"github.com/cloudbase/garm/client"
apiClientFirstRun "github.com/cloudbase/garm/client/first_run"
apiClientLogin "github.com/cloudbase/garm/client/login"
"github.com/cloudbase/garm/params"
"github.com/go-openapi/runtime"
openapiRuntimeClient "github.com/go-openapi/runtime/client"
"sigs.k8s.io/controller-runtime/pkg/log"

"github.com/mercedes-benz/garm-operator/pkg/metrics"
)
Expand All @@ -21,6 +25,7 @@ type GarmScopeParams struct {
Username string
Password string
Debug bool
Email string
}

func newGarmClient(garmParams GarmScopeParams) (*client.GarmAPI, runtime.ClientAuthInfoWriter, error) {
Expand Down Expand Up @@ -73,3 +78,44 @@ func newGarmClient(garmParams GarmScopeParams) (*client.GarmAPI, runtime.ClientA

return apiCli, authToken, nil
}

func initializeGarm(ctx context.Context, garmParams GarmScopeParams) error {
log := log.FromContext(ctx)

newUserReq := apiClientFirstRun.NewFirstRunParams()
newUserReq.Body = params.NewUserParams{
Username: garmParams.Username,
Password: garmParams.Password,
Email: garmParams.Email,
}

baseURLParsed, err := url.Parse(garmParams.BaseURL)
if err != nil {
return fmt.Errorf("failed to parse base url %s: %s", garmParams.BaseURL, err)
}

apiPath, err := url.JoinPath(baseURLParsed.Path, client.DefaultBasePath)
if err != nil {
return fmt.Errorf("failed to join base url path %s with %s: %s", baseURLParsed.Path, client.DefaultBasePath, err)
}

transportCfg := client.DefaultTransportConfig().
WithHost(baseURLParsed.Host).
WithBasePath(apiPath).
WithSchemes([]string{baseURLParsed.Scheme})
apiCli := client.NewHTTPClientWithConfig(nil, transportCfg)
authToken := openapiRuntimeClient.BearerToken("")

resp, err := apiCli.FirstRun.FirstRun(newUserReq, authToken)
if err != nil {
if strings.Contains(err.Error(), "(status 409)") {
log.Info("Garm is already initialized")
return nil
}
return fmt.Errorf("failed to initialize garm: %s", err)
}

log.Info("Garm initialized successfully with the following User", "ID", resp.Payload.ID, "username", resp.Payload.Username, "email", resp.Payload.Email, "enabled", resp.Payload.Enabled)

return nil
}
30 changes: 30 additions & 0 deletions pkg/client/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT

package client

import (
"context"

"github.com/mercedes-benz/garm-operator/pkg/metrics"
)

type InitClient interface {
Init(ctx context.Context, garmParams GarmScopeParams) error
}

type initClient struct{}

func NewInitClient() InitClient {
return &initClient{}
}

func (s *initClient) Init(ctx context.Context, garmParams GarmScopeParams) error {
metrics.TotalGarmCalls.WithLabelValues("Init").Inc()
err := initializeGarm(ctx, garmParams)
if err != nil {
metrics.GarmCallErrors.WithLabelValues("Init").Inc()
return err
}

return nil
}
2 changes: 2 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type GarmConfig struct {
Server string `koanf:"server" validate:"required,url"`
Username string `koanf:"username" validate:"required"`
Password string `koanf:"password" validate:"required"`
Init bool `koanf:"init"`
Email string `koanf:"email" validate:"required_if=Init true"`
}

type OperatorConfig struct {
Expand Down
8 changes: 8 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func TestGenerateConfig(t *testing.T) {
Server: "http://localhost:9997",
Username: "admin",
Password: "password",
Init: false,
Email: "",
},
},
},
Expand All @@ -65,6 +67,8 @@ func TestGenerateConfig(t *testing.T) {
Server: "http://localhost:9997",
Username: "admin",
Password: "password",
Init: false,
Email: "",
},
},
},
Expand Down Expand Up @@ -92,6 +96,8 @@ func TestGenerateConfig(t *testing.T) {
Server: "http://localhost:9997",
Username: "admin",
Password: "password",
Init: false,
Email: "",
},
},
},
Expand All @@ -118,6 +124,8 @@ func TestGenerateConfig(t *testing.T) {
Server: "http://garm-server:9997",
Username: "garm-username",
Password: "garm-password",
Init: false,
Email: "",
},
},
},
Expand Down
2 changes: 2 additions & 0 deletions pkg/config/test_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ garm:
username: "garm-username"
password: "garm-password"
server: "http://garm-server:9997"
init: false
email: ""

operator:
metrics_bind_address: ":7000"
Expand Down
4 changes: 4 additions & 0 deletions pkg/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ const (
DefaultLeaderElection = false
DefaultSyncPeriod = 5 * time.Minute
DefaultWatchNamespace = ""

// default values for garm configuration
DefaultGarmInit = false
DefaultGarmEmail = ""
)
2 changes: 2 additions & 0 deletions pkg/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ func InitiateFlags() *pflag.FlagSet {
f.String("garm-server", "", "The address of the GARM server")
f.String("garm-username", "", "The username for the GARM server")
f.String("garm-password", "", "The password for the GARM server")
f.Bool("garm-init", defaults.DefaultGarmInit, "Enable initialization of new GARM Instance")
f.String("garm-email", defaults.DefaultGarmEmail, "The email address for the GARM server (only required if garm-init is set to true)")

f.Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")

Expand Down

0 comments on commit 64817f7

Please sign in to comment.