Skip to content

Commit e2bddb2

Browse files
committed
Added some new conditions for HarvesterCluster resource
Signed-off-by: Mohamed Belgaied Hassine <belgaied2@hotmail.com>
1 parent 864fe91 commit e2bddb2

3 files changed

Lines changed: 119 additions & 2 deletions

File tree

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,8 @@ tilt-provider.json
3434
.devcontainer/
3535

3636
# All environment variables should be added to .env file
37-
*.env
37+
*.env
38+
39+
# Aider files
40+
.aider.*
41+
conditions-adding.md

api/v1alpha1/harvestercluster_types.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ const (
6565
InfrastructureProvisioningFailedReason = "InfrastructureProvisioningFailed"
6666
// InfrastructureReadyReason documents that all infrastructure components are ready.
6767
InfrastructureReadyReason = "InfrastructureReady"
68+
69+
// TargetNamespaceReadyCondition indicates the target namespace in Harvester exists and is accessible.
70+
TargetNamespaceReadyCondition clusterv1.ConditionType = "TargetNamespaceReady"
71+
// TargetNamespaceNotReadyReason documents that the target namespace does not exist or is not accessible.
72+
TargetNamespaceNotReadyReason = "TargetNamespaceNotReady"
73+
// TargetNamespaceReadyReason documents that the target namespace exists and is accessible.
74+
TargetNamespaceReadyReason = "TargetNamespaceReady"
75+
76+
// HarvesterConnectionReadyCondition indicates successful connection/authentication to Harvester API.
77+
HarvesterConnectionReadyCondition clusterv1.ConditionType = "HarvesterConnectionReady"
78+
// HarvesterConnectionFailedReason documents that connection to Harvester API failed.
79+
HarvesterConnectionFailedReason = "HarvesterConnectionFailed"
80+
// HarvesterAuthenticationFailedReason documents that authentication to Harvester API failed.
81+
HarvesterAuthenticationFailedReason = "HarvesterAuthenticationFailed"
82+
// HarvesterConnectionReadyReason documents that connection and authentication to Harvester API is successful.
83+
HarvesterConnectionReadyReason = "HarvesterConnectionReady"
6884
)
6985

7086
const (

internal/controller/harvestercluster_controller.go

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ func (r *HarvesterClusterReconciler) ReconcileNormal(scope *ClusterScope) (res c
231231
return ctrl.Result{}, nil
232232
}
233233

234+
// Set TargetNamespaceReady condition to in progress
235+
conditions.Set(scope.HarvesterCluster, &clusterv1.Condition{
236+
Type: infrav1.TargetNamespaceReadyCondition,
237+
Status: apiv1.ConditionFalse,
238+
Reason: "TargetNamespaceChecking",
239+
Message: "Checking if target namespace exists",
240+
})
241+
234242
// Check if TargetNamespace exists, if not create it
235243
_, err = scope.HarvesterClient.CoreV1().Namespaces().Get(context.TODO(), scope.HarvesterCluster.Spec.TargetNamespace, v1.GetOptions{})
236244
if err != nil {
@@ -242,10 +250,41 @@ func (r *HarvesterClusterReconciler) ReconcileNormal(scope *ClusterScope) (res c
242250
}, v1.CreateOptions{})
243251
if err != nil {
244252
logger.Error(err, "unable to create TargetNamespace")
253+
254+
conditions.Set(scope.HarvesterCluster, &clusterv1.Condition{
255+
Type: infrav1.TargetNamespaceReadyCondition,
256+
Status: apiv1.ConditionFalse,
257+
Reason: infrav1.TargetNamespaceNotReadyReason,
258+
Message: fmt.Sprintf("Failed to create target namespace: %v", err),
259+
})
260+
} else {
261+
logger.Error(err, "unable to get TargetNamespace in Harvester, problem with the HarvesterClient")
262+
263+
conditions.Set(scope.HarvesterCluster, &clusterv1.Condition{
264+
Type: infrav1.TargetNamespaceReadyCondition,
265+
Status: apiv1.ConditionFalse,
266+
Reason: infrav1.TargetNamespaceNotReadyReason,
267+
Message: fmt.Sprintf("Unable to access target namespace: %v", err),
268+
})
245269
}
246270
} else {
247271
logger.Error(err, "unable to get TargetNamespace in Harvester, problem with the HarvesterClient")
272+
273+
conditions.Set(scope.HarvesterCluster, &clusterv1.Condition{
274+
Type: infrav1.TargetNamespaceReadyCondition,
275+
Status: apiv1.ConditionFalse,
276+
Reason: infrav1.TargetNamespaceNotReadyReason,
277+
Message: fmt.Sprintf("Unable to access target namespace: %v", err),
278+
})
248279
}
280+
} else {
281+
// Target namespace exists and is accessible
282+
conditions.Set(scope.HarvesterCluster, &clusterv1.Condition{
283+
Type: infrav1.TargetNamespaceReadyCondition,
284+
Status: apiv1.ConditionTrue,
285+
Reason: infrav1.TargetNamespaceReadyReason,
286+
Message: "Target namespace exists and is accessible",
287+
})
249288
}
250289

251290
// Initializing return values
@@ -748,12 +787,27 @@ func (r *HarvesterClusterReconciler) reconcileCloudProviderConfig(scope *Cluster
748787
func (r *HarvesterClusterReconciler) reconcileHarvesterConfig(ctx context.Context, cluster *infrav1.HarvesterCluster) (*rest.Config, error) {
749788
logger := log.FromContext(ctx)
750789

790+
// Set HarvesterConnectionReady condition to in progress
791+
conditions.Set(cluster, &clusterv1.Condition{
792+
Type: infrav1.HarvesterConnectionReadyCondition,
793+
Status: apiv1.ConditionFalse,
794+
Reason: "HarvesterConnectionInProgress",
795+
Message: "Attempting to connect to Harvester",
796+
})
797+
751798
secret, err := locutil.GetSecretForHarvesterConfig(ctx, cluster, r.Client)
752799
if (err != nil || secret == &apiv1.Secret{}) {
753800
cluster.Status.FailureReason = "IdentitySecretUnavailable"
754801
cluster.Status.FailureMessage = "unable to find the IdentitySecret for Harvester"
755802
cluster.Status.Ready = false
756803

804+
conditions.Set(cluster, &clusterv1.Condition{
805+
Type: infrav1.HarvesterConnectionReadyCondition,
806+
Status: apiv1.ConditionFalse,
807+
Reason: infrav1.HarvesterAuthenticationFailedReason,
808+
Message: fmt.Sprintf("Failed to get IdentitySecret: %v", err),
809+
})
810+
757811
return &rest.Config{}, errors.Wrapf(err, "unable to find the IdentitySecret for Harvester %s", ctx)
758812
}
759813

@@ -765,6 +819,13 @@ func (r *HarvesterClusterReconciler) reconcileHarvesterConfig(ctx context.Contex
765819
cluster.Status.FailureMessage = err.Error()
766820
cluster.Status.Ready = false
767821

822+
conditions.Set(cluster, &clusterv1.Condition{
823+
Type: infrav1.HarvesterConnectionReadyCondition,
824+
Status: apiv1.ConditionFalse,
825+
Reason: infrav1.HarvesterAuthenticationFailedReason,
826+
Message: fmt.Sprintf("Invalid kubeconfig: %v", err),
827+
})
828+
768829
return &rest.Config{}, err
769830
}
770831

@@ -777,29 +838,65 @@ func (r *HarvesterClusterReconciler) reconcileHarvesterConfig(ctx context.Contex
777838
if err != nil {
778839
logger.Error(err, "unable to create kubernetes client config for Harvester")
779840

841+
conditions.Set(cluster, &clusterv1.Condition{
842+
Type: infrav1.HarvesterConnectionReadyCondition,
843+
Status: apiv1.ConditionFalse,
844+
Reason: infrav1.HarvesterConnectionFailedReason,
845+
Message: fmt.Sprintf("Failed to create REST config: %v", err),
846+
})
847+
780848
return &rest.Config{}, err
781849
}
782850

783851
hvClient, err := kubeclient.NewForConfig(hvRESTConfig)
784852
if err != nil {
785853
logger.Error(err, "unable to create kubernetes client from restConfig")
786854

855+
conditions.Set(cluster, &clusterv1.Condition{
856+
Type: infrav1.HarvesterConnectionReadyCondition,
857+
Status: apiv1.ConditionFalse,
858+
Reason: infrav1.HarvesterConnectionFailedReason,
859+
Message: fmt.Sprintf("Failed to create Kubernetes client: %v", err),
860+
})
861+
787862
return &rest.Config{}, err
788863
}
789864

790865
harvesterDeployment, err := hvClient.AppsV1().Deployments(harvesterNamespace).Get(ctx, harvesterDeploymentName, v1.GetOptions{})
791866
if err != nil {
792867
logger.Error(err, "Harvester deployment not found on target Kubernetes cluster")
793868

869+
conditions.Set(cluster, &clusterv1.Condition{
870+
Type: infrav1.HarvesterConnectionReadyCondition,
871+
Status: apiv1.ConditionFalse,
872+
Reason: infrav1.HarvesterConnectionFailedReason,
873+
Message: fmt.Sprintf("Harvester deployment not found: %v", err),
874+
})
875+
794876
return &rest.Config{}, err
795877
}
796878

797879
if !isHarvesterAvailable(harvesterDeployment.Status.Conditions) {
798880
logger.Error(err, "harvester cluster is unavailable")
799881

800-
return &rest.Config{}, err
882+
conditions.Set(cluster, &clusterv1.Condition{
883+
Type: infrav1.HarvesterConnectionReadyCondition,
884+
Status: apiv1.ConditionFalse,
885+
Reason: infrav1.HarvesterConnectionFailedReason,
886+
Message: "Harvester cluster is unavailable",
887+
})
888+
889+
return &rest.Config{}, errors.New("harvester cluster is unavailable")
801890
}
802891

892+
// Set HarvesterConnectionReady condition to true
893+
conditions.Set(cluster, &clusterv1.Condition{
894+
Type: infrav1.HarvesterConnectionReadyCondition,
895+
Status: apiv1.ConditionTrue,
896+
Reason: infrav1.HarvesterConnectionReadyReason,
897+
Message: "Successfully connected and authenticated to Harvester API",
898+
})
899+
803900
return hvRESTConfig, nil
804901
}
805902

0 commit comments

Comments
 (0)