Skip to content

Commit

Permalink
naive bios management job implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Bortnikov <[email protected]>
  • Loading branch information
aobort committed Oct 7, 2024
1 parent e663a97 commit b87e059
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 25 deletions.
77 changes: 77 additions & 0 deletions cmd/jobbios/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package main

import (
"flag"
"os"

metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1"
"github.com/ironcore-dev/metal-operator/internal/job"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
)

func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(metalv1alpha1.AddToScheme(scheme))
// +kubebuilder:scaffold:scheme
}

func main() {
var (
jobTypeString string
serverBIOSRef string
insecure bool
)

pflag.StringVar(&jobTypeString, "job-type", "", "job type")
pflag.StringVar(&serverBIOSRef, "server-bios-ref", "", "server bios ref")
pflag.BoolVar(&insecure, "insecure", true, "use insecure connection to BMC")

opts := zap.Options{
Development: true,
}
opts.BindFlags(flag.CommandLine)
flag.Parse()

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

if jobTypeString == "" {
setupLog.Error(nil, "job type is required")
os.Exit(1)
}

if serverBIOSRef == "" {
setupLog.Error(nil, "server bios ref is required")
os.Exit(1)
}

config, err := rest.InClusterConfig()
if err != nil {
setupLog.Error(err, "unable to get in cluster config")
os.Exit(1)
}
kubeClient, err := client.New(config, client.Options{
Scheme: scheme,
})
if err != nil {
setupLog.Error(err, "unable to create kubernetes client")
os.Exit(1)
}

executor := job.New(kubeClient)
ctx := ctrl.SetupSignalHandler()
if err = executor.Run(ctx, jobTypeString, serverBIOSRef); err != nil {
os.Exit(1)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: Apache-2.0

package controller
package bmcutils

import (
"context"
Expand All @@ -10,11 +10,10 @@ import (

metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1"
"github.com/ironcore-dev/metal-operator/bmc"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

const DefaultKubeNamespace = "default"

func GetBMCClientForServer(ctx context.Context, c client.Client, server *metalv1alpha1.Server, insecure bool) (bmc.BMC, error) {
if server.Spec.BMCRef != nil {
b := &metalv1alpha1.BMC{}
Expand Down Expand Up @@ -94,7 +93,7 @@ func CreateBMCClient(ctx context.Context, c client.Client, insecure bool, bmcPro
if err != nil {
return nil, fmt.Errorf("failed to get credentials from BMC secret: %w", err)
}
bmcClient, err = bmc.NewRedfishKubeBMCClient(ctx, bmcAddress, username, password, true, c, DefaultKubeNamespace)
bmcClient, err = bmc.NewRedfishKubeBMCClient(ctx, bmcAddress, username, password, true, c, metav1.NamespaceDefault)
if err != nil {
return nil, fmt.Errorf("failed to create Redfish client: %w", err)
}
Expand Down
17 changes: 9 additions & 8 deletions internal/controller/bmc_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"fmt"

"github.com/ironcore-dev/metal-operator/internal/bmcutils"
"k8s.io/apimachinery/pkg/api/errors"

"github.com/go-logr/logr"
Expand All @@ -29,11 +30,11 @@ type BMCReconciler struct {
Insecure bool
}

//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints,verbs=get;list;watch
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcsecrets,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs/finalizers,verbs=update
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints,verbs=get;list;watch
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcsecrets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs/finalizers,verbs=update

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
Expand Down Expand Up @@ -102,7 +103,7 @@ func (r *BMCReconciler) updateBMCStatusDetails(ctx context.Context, log logr.Log
return fmt.Errorf("failed to patch IP and MAC address status: %w", err)
}

bmcClient, err := GetBMCClientFromBMC(ctx, r.Client, bmcObj, r.Insecure)
bmcClient, err := bmcutils.GetBMCClientFromBMC(ctx, r.Client, bmcObj, r.Insecure)
if err != nil {
return fmt.Errorf("failed to create BMC client: %w", err)
}
Expand Down Expand Up @@ -132,7 +133,7 @@ func (r *BMCReconciler) updateBMCStatusDetails(ctx context.Context, log logr.Log
}

func (r *BMCReconciler) discoverServers(ctx context.Context, log logr.Logger, bmcObj *metalv1alpha1.BMC) error {
bmcClient, err := GetBMCClientFromBMC(ctx, r.Client, bmcObj, r.Insecure)
bmcClient, err := bmcutils.GetBMCClientFromBMC(ctx, r.Client, bmcObj, r.Insecure)
if err != nil {
return fmt.Errorf("failed to create BMC client: %w", err)
}
Expand All @@ -149,7 +150,7 @@ func (r *BMCReconciler) discoverServers(ctx context.Context, log logr.Logger, bm
Kind: "Server",
},
ObjectMeta: metav1.ObjectMeta{
Name: GetServerNameFromBMCandIndex(i, bmcObj),
Name: bmcutils.GetServerNameFromBMCandIndex(i, bmcObj),
},
Spec: metalv1alpha1.ServerSpec{
UUID: s.UUID,
Expand Down
5 changes: 3 additions & 2 deletions internal/controller/bmc_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package controller

import (
metalv1alpha1 "github.com/ironcore-dev/metal-operator/api/v1alpha1"
"github.com/ironcore-dev/metal-operator/internal/bmcutils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -51,7 +52,7 @@ var _ = Describe("BMC Controller", func() {
By("Ensuring that the Server resource will be removed")
server := &metalv1alpha1.Server{
ObjectMeta: metav1.ObjectMeta{
Name: GetServerNameFromBMCandIndex(0, bmc),
Name: bmcutils.GetServerNameFromBMCandIndex(0, bmc),
},
}
DeferCleanup(k8sClient.Delete, server)
Expand Down Expand Up @@ -84,7 +85,7 @@ var _ = Describe("BMC Controller", func() {
By("Ensuring that the Server resource has been created")
server := &metalv1alpha1.Server{
ObjectMeta: metav1.ObjectMeta{
Name: GetServerNameFromBMCandIndex(0, bmc),
Name: bmcutils.GetServerNameFromBMCandIndex(0, bmc),
},
}
Eventually(Object(server)).Should(SatisfyAll(
Expand Down
12 changes: 6 additions & 6 deletions internal/controller/endpoint_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ type EndpointReconciler struct {
Insecure bool
}

//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcsecrets,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints/finalizers,verbs=update
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcs,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=bmcsecrets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=endpoints/finalizers,verbs=update

func (r *EndpointReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := ctrl.LoggerFrom(ctx)
Expand Down Expand Up @@ -125,7 +125,7 @@ func (r *EndpointReconciler) reconcile(ctx context.Context, log logr.Logger, end
case metalv1alpha1.ProtocolRedfishKube:
log.V(1).Info("Creating client for a kube test BMC")
bmcAddress := fmt.Sprintf("%s://%s:%d", r.getProtocol(), endpoint.Spec.IP, m.Port)
bmcClient, err := bmc.NewRedfishKubeBMCClient(ctx, bmcAddress, m.DefaultCredentials[0].Username, m.DefaultCredentials[0].Password, true, r.Client, DefaultKubeNamespace)
bmcClient, err := bmc.NewRedfishKubeBMCClient(ctx, bmcAddress, m.DefaultCredentials[0].Username, m.DefaultCredentials[0].Password, true, r.Client, metav1.NamespaceDefault)
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to create BMC client: %w", err)
}
Expand Down
11 changes: 6 additions & 5 deletions internal/controller/server_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

"github.com/ironcore-dev/metal-operator/bmc"
"github.com/ironcore-dev/metal-operator/internal/bmcutils"
"k8s.io/apimachinery/pkg/util/wait"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -361,7 +362,7 @@ func (r *ServerReconciler) updateServerStatus(ctx context.Context, log logr.Logg
log.V(1).Info("Server has no BMC connection configured")
return nil
}
bmcClient, err := GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
bmcClient, err := bmcutils.GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
if err != nil {
return fmt.Errorf("failed to create BMC client: %w", err)
}
Expand Down Expand Up @@ -538,7 +539,7 @@ func (r *ServerReconciler) pxeBootServer(ctx context.Context, log logr.Logger, s
return fmt.Errorf("can only PXE boot server with valid BMC ref or inline BMC configuration")
}

bmcClient, err := GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
bmcClient, err := bmcutils.GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
defer func() {
if bmcClient != nil {
bmcClient.Logout()
Expand Down Expand Up @@ -629,7 +630,7 @@ func (r *ServerReconciler) ensureServerPowerState(ctx context.Context, log logr.
return nil
}

bmcClient, err := GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
bmcClient, err := bmcutils.GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
defer func() {
if bmcClient != nil {
bmcClient.Logout()
Expand Down Expand Up @@ -751,7 +752,7 @@ func (r *ServerReconciler) applyBootOrder(ctx context.Context, log logr.Logger,
log.V(1).Info("Server has no BMC connection configured")
return nil
}
bmcClient, err := GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
bmcClient, err := bmcutils.GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
if err != nil {
return fmt.Errorf("failed to create BMC client: %w", err)
}
Expand Down Expand Up @@ -785,7 +786,7 @@ func (r *ServerReconciler) handleAnnotionOperations(ctx context.Context, log log
if !ok {
return false, nil
}
bmcClient, err := GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
bmcClient, err := bmcutils.GetBMCClientForServer(ctx, r.Client, server, r.Insecure)
if err != nil {
return false, fmt.Errorf("failed to create BMC client: %w", err)
}
Expand Down
6 changes: 6 additions & 0 deletions internal/controller/serverbios_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package controller
import (
"context"
"fmt"
"strconv"
"time"

"github.com/go-logr/logr"
Expand All @@ -29,6 +30,7 @@ type ServerBIOSReconciler struct {
client.Client
Scheme *runtime.Scheme

Insecure bool
// todo: need to decide how to provide jobs' configuration to controller
JobNamespace string
JobImage string
Expand Down Expand Up @@ -283,6 +285,10 @@ func (r *ServerBIOSReconciler) createJob(
Name: "SERVER_BIOS_REF",
Value: serverBIOS.Name,
},
{
Name: "INSECURE",
Value: strconv.FormatBool(r.Insecure),
},
},
},
},
Expand Down
Loading

0 comments on commit b87e059

Please sign in to comment.