Skip to content
Merged
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
73 changes: 42 additions & 31 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ var Options struct {
ApproveCsrsRequeueDuration time.Duration `envconfig:"APPROVE_CSRS_REQUEUE_DURATION" default:"1m"`
HTTPListenPort string `envconfig:"HTTP_LISTEN_PORT" default:""`
AllowConvergedFlow bool `envconfig:"ALLOW_CONVERGED_FLOW" default:"true"`
EnableMetal3 bool `envconfig:"ENABLE_METAL3" default:"true"`
PauseProvisionedBMHs bool `envconfig:"PAUSE_PROVISIONED_BMHS" default:"true"`
ForceInsecurePolicyJson bool `envconfig:"FORCE_INSECURE_POLICY_JSON" default:"false"`
PreprovisioningImageControllerConfig controllers.PreprovisioningImageControllerConfig
Expand Down Expand Up @@ -291,17 +292,7 @@ func startKubeAPIControllers(
}
}

failOnError(doesBMHCRDExist(ctrlMgr), "BareMetalHost CRD does not exist in cluster")
clientConfig := ctrl.GetConfigOrDie()
osClient := osclientset.NewForConfigOrDie(clientConfig)
kubeClient := kubernetes.NewForConfigOrDie(clientConfig)
bmoUtils := controllers.NewBMOUtils(ctrlMgr.GetAPIReader(),
osClient,
kubeClient,
log.WithField("pkg", "baremetal_operator_utils"),
Options.EnableKubeAPI,
)
useConvergedFlow := Options.AllowConvergedFlow && bmoUtils.ConvergedFlowAvailable()
bmoUtils, useConvergedFlow := getBMOUtils(ctrlMgr, log)

c := ctrlMgr.GetClient()
r := ctrlMgr.GetAPIReader()
Expand Down Expand Up @@ -358,9 +349,10 @@ func startKubeAPIControllers(
AgentContainerImage: Options.BMConfig.AgentDockerImg,
HostFSMountDir: hostFSMountDir,
ImageServiceEnabled: Options.EnableImageService,
EnableMetal3: Options.EnableMetal3,
}).SetupWithManager(ctrlMgr), "unable to create controller Agent")

if Options.EnableImageService {
if Options.EnableMetal3 && Options.EnableImageService {
failOnError((&controllers.BMACReconciler{
Client: ctrlMgr.GetClient(),
APIReader: ctrlMgr.GetAPIReader(),
Expand Down Expand Up @@ -390,7 +382,7 @@ func startKubeAPIControllers(
Log: log,
}).SetupWithManager(ctrlMgr), "unable to create controller AgentLabel")

if Options.EnableImageService && useConvergedFlow {
if Options.EnableMetal3 && Options.EnableImageService && useConvergedFlow {
failOnError((&controllers.PreprovisioningImageReconciler{
Client: ctrlMgr.GetClient(),
Log: log,
Expand Down Expand Up @@ -950,24 +942,27 @@ func createControllerManager() (manager.Manager, error) {
return nil, err

}
cacheByObject := map[client.Object]cache.ByObject{
&corev1.Secret{}: {
Label: labels.SelectorFromSet(
labels.Set{
controllers.WatchResourceLabel: controllers.WatchResourceValue,
},
),
},
}
if Options.EnableMetal3 {
cacheByObject[&metal3_v1alpha1.PreprovisioningImage{}] = cache.ByObject{
Label: labels.NewSelector().Add(*infraenvLabel),
}
}
return ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: schemes,
WebhookServer: webhook.NewServer(webhook.Options{Port: 9443}),
LeaderElection: true,
LeaderElectionID: "77190dcb.agent-install.openshift.io",
Cache: cache.Options{
ByObject: map[client.Object]cache.ByObject{
&corev1.Secret{}: {
Label: labels.SelectorFromSet(
labels.Set{
controllers.WatchResourceLabel: controllers.WatchResourceValue,
},
),
},
&metal3_v1alpha1.PreprovisioningImage{}: {
Label: labels.NewSelector().Add(*infraenvLabel),
},
},
ByObject: cacheByObject,
},
})
}
Expand Down Expand Up @@ -1035,15 +1030,31 @@ func getNotificationStream(log *logrus.Logger) *stream.NotificationStream {
return stream.NewNotificationStream(writer, log, metadata)
}

func doesBMHCRDExist(mgr manager.Manager) error {
gvk, err := apiutil.GVKForObject(&metal3_v1alpha1.BareMetalHost{}, mgr.GetScheme())
func getBMOUtils(ctrlMgr manager.Manager, log *logrus.Logger) (controllers.BMOUtils, bool) {
if !Options.EnableMetal3 {
log.Info("Metal3 integration is disabled (ENABLE_METAL3=false)")
return nil, false
}

gvk, err := apiutil.GVKForObject(&metal3_v1alpha1.BareMetalHost{}, ctrlMgr.GetScheme())
if err != nil {
return err
log.WithError(err).Fatal("BareMetalHost CRD does not exist in cluster")
}
if _, err = mgr.GetRESTMapper().RESTMapping(gvk.GroupKind(), gvk.Version); err != nil {
return err
if _, err = ctrlMgr.GetRESTMapper().RESTMapping(gvk.GroupKind(), gvk.Version); err != nil {
log.WithError(err).Fatal("BareMetalHost CRD does not exist in cluster")
}
return nil

clientConfig := ctrl.GetConfigOrDie()
osClient := osclientset.NewForConfigOrDie(clientConfig)
kubeClient := kubernetes.NewForConfigOrDie(clientConfig)
bmoUtils := controllers.NewBMOUtils(ctrlMgr.GetAPIReader(),
osClient,
kubeClient,
log.WithField("pkg", "baremetal_operator_utils"),
Options.EnableKubeAPI,
)
useConvergedFlow := Options.AllowConvergedFlow && bmoUtils.ConvergedFlowAvailable()
return bmoUtils, useConvergedFlow
}

func startPPROF(log *logrus.Logger) {
Expand Down
7 changes: 7 additions & 0 deletions internal/controller/controllers/agent_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type AgentReconciler struct {
HostFSMountDir string
reclaimer *agentReclaimer
ImageServiceEnabled bool
EnableMetal3 bool
}

// +kubebuilder:rbac:groups=agent-install.openshift.io,resources=agents,verbs=get;list;watch;create;update;patch;delete
Expand Down Expand Up @@ -682,6 +683,9 @@ func (r *AgentReconciler) tryApproveDay2CSRs(ctx context.Context, agent *aiv1bet
}

func (r *AgentReconciler) getBMH(ctx context.Context, agent *aiv1beta1.Agent) (*bmh_v1alpha1.BareMetalHost, error) {
if !r.EnableMetal3 {
return nil, nil
}
bmhName, ok := agent.ObjectMeta.Labels[AGENT_BMH_LABEL]
if !ok {
return nil, nil
Expand All @@ -698,6 +702,9 @@ func (r *AgentReconciler) getBMH(ctx context.Context, agent *aiv1beta1.Agent) (*
}

func (r *AgentReconciler) bmhExists(ctx context.Context, agent *aiv1beta1.Agent) (bool, error) {
if !r.EnableMetal3 {
return false, nil
}
bmh, err := r.getBMH(ctx, agent)
if err != nil {
return false, err
Expand Down
77 changes: 77 additions & 0 deletions internal/controller/controllers/agent_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ var _ = Describe("agent reconcile", func() {
hr = &AgentReconciler{
Client: c,
ImageServiceEnabled: true,
EnableMetal3: true,
APIReader: c,
Scheme: scheme.Scheme,
Log: common.GetTestLog(),
Expand Down Expand Up @@ -1445,6 +1446,77 @@ var _ = Describe("agent reconcile", func() {
Expect(result).To(Equal(ctrl.Result{}))
assertAgentConditionsSuccess()
})

It("unbind attempts to reclaim when Metal3 is disabled even if BMH label is set", func() {
hr.EnableMetal3 = false
defer func() { hr.EnableMetal3 = true }()

testMAC := "de:ad:be:ef:00:00"
bmh := newBMH("testBMH", &bmh_v1alpha1.BareMetalHostSpec{BootMACAddress: testMAC})
Expect(c.Create(ctx, bmh)).To(Succeed())

if host.ObjectMeta.Labels == nil {
host.ObjectMeta.Labels = make(map[string]string)
}
host.ObjectMeta.Labels[AGENT_BMH_LABEL] = bmh.Name
Expect(c.Update(ctx, host)).To(Succeed())

createKubeconfigSecret()
expectDBClusterWithKubeKeys()

mockClient := spoke_k8s_client.NewMockSpokeK8sClient(mockCtrl)
mockClientFactory.EXPECT().CreateFromSecret(gomock.Any(), gomock.Any()).Return(mockClient, nil).AnyTimes()
mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.AssignableToTypeOf(&corev1.Namespace{})).Return(nil)
mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.AssignableToTypeOf(&corev1.ServiceAccount{})).Return(nil)
mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.AssignableToTypeOf(&authzv1.Role{})).Return(nil)
mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.AssignableToTypeOf(&authzv1.RoleBinding{})).Return(nil)
mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.AssignableToTypeOf(&corev1.Secret{})).Return(nil)
mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.AssignableToTypeOf(&corev1.Node{})).Return(nil)
mockClient.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.AssignableToTypeOf(&appsv1.DaemonSet{})).Return(nil)
mockClient.EXPECT().Update(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()

mockInstallerInternal.EXPECT().UnbindHostInternal(gomock.Any(), gomock.Any(), true, bminventory.NonInteractive).Return(commonHost, nil)
result, err := hr.Reconcile(ctx, newHostRequest(host))
Expect(err).To(BeNil())
Expect(result).To(Equal(ctrl.Result{}))
assertAgentConditionsSuccess()
})
})

Context("Metal3 disabled", func() {
It("getBMH returns nil even when BMH exists and label is set", func() {
hr.EnableMetal3 = false
defer func() { hr.EnableMetal3 = true }()

bmh := newBMH("testBMH", &bmh_v1alpha1.BareMetalHostSpec{})
Expect(c.Create(ctx, bmh)).To(Succeed())

hostId := strfmt.UUID(uuid.New().String())
agent := newAgent(hostId.String(), testNamespace, v1beta1.AgentSpec{})
agent.ObjectMeta.Labels = map[string]string{AGENT_BMH_LABEL: bmh.Name}
Expect(c.Create(ctx, agent)).To(Succeed())

result, err := hr.getBMH(ctx, agent)
Expect(err).To(BeNil())
Expect(result).To(BeNil())
})

It("bmhExists returns false even when BMH exists and label is set", func() {
hr.EnableMetal3 = false
defer func() { hr.EnableMetal3 = true }()

bmh := newBMH("testBMH2", &bmh_v1alpha1.BareMetalHostSpec{})
Expect(c.Create(ctx, bmh)).To(Succeed())

hostId := strfmt.UUID(uuid.New().String())
agent := newAgent(hostId.String(), testNamespace, v1beta1.AgentSpec{})
agent.ObjectMeta.Labels = map[string]string{AGENT_BMH_LABEL: bmh.Name}
Expect(c.Create(ctx, agent)).To(Succeed())

exists, err := hr.bmhExists(ctx, agent)
Expect(err).To(BeNil())
Expect(exists).To(BeFalse())
})
})

It("Agent status update does not fail when unbind fails", func() {
Expand Down Expand Up @@ -2997,6 +3069,7 @@ VU1eS0RiS/Lz6HwRs2mATNY5FrpZOgdM3cI=
SpokeK8sClientFactory: mockClientFactory,
ApproveCsrsRequeueDuration: time.Minute,
ImageServiceEnabled: true,
EnableMetal3: true,
}
sId := strfmt.UUID(uuid.New().String())
hostId = strfmt.UUID(uuid.New().String())
Expand Down Expand Up @@ -4056,6 +4129,7 @@ var _ = Describe("TestConditions", func() {
hr = &AgentReconciler{
Client: c,
ImageServiceEnabled: true,
EnableMetal3: true,
Scheme: scheme.Scheme,
Log: common.GetTestLog(),
Installer: mockInstallerInternal,
Expand Down Expand Up @@ -4805,6 +4879,7 @@ var _ = Describe("spokeKubeClient", func() {
APIReader: c,
SpokeK8sClientFactory: mockClientFactory,
ImageServiceEnabled: true,
EnableMetal3: true,
}
cdSpec = hivev1.ClusterDeploymentSpec{
ClusterName: clusterName,
Expand Down Expand Up @@ -4911,6 +4986,7 @@ var _ = Describe("handleAgentFinalizer", func() {
Installer: mockInstallerInternal,
SpokeK8sClientFactory: mockClientFactory,
ImageServiceEnabled: true,
EnableMetal3: true,
}

agent = &v1beta1.Agent{
Expand Down Expand Up @@ -5477,6 +5553,7 @@ var _ = Describe("Restore Host - Reconcile an Agent with missing Host", func() {
SpokeK8sClientFactory: mockClientFactory,
AgentContainerImage: agentImage,
ImageServiceEnabled: true,
EnableMetal3: true,
}
sId = strfmt.UUID(uuid.New().String())
backEndCluster = &common.Cluster{Cluster: models.Cluster{ID: &sId}}
Expand Down