Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌱 vspheredeploymentzone/vsphereclusteridentity: implement v1beta2 conditions, govmomi #3401

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
21 changes: 21 additions & 0 deletions apis/v1beta1/vsphereclusteridentity_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,27 @@ const (
VSphereClusterIdentityFinalizer = "vsphereclusteridentity/infrastructure.cluster.x-k8s.io"
)

// VSphereClusterIdentity's CredentialsAvailable condition and corresponding reasons that will be used in v1Beta2 API version.
const (
// VSphereClusterIdentityCredentialsAvailableV1Beta2Condition documents the status of the credentials for a VSphereClusterIdentity.
VSphereClusterIdentityCredentialsAvailableV1Beta2Condition = "CredentialsAvailable"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if this should be just Available


// VSphereClusterIdentityCredentialsAvailableV1Beta2Reason surfaces when the VSphereClusterIdentity credentials are available.
VSphereClusterIdentityCredentialsAvailableV1Beta2Reason = clusterv1.AvailableV1Beta2Reason

// VSphereClusterIdentityCredentialsSecretNotAvailableV1Beta2Reason surfaces when the VSphereClusterIdentity secret is not available.
VSphereClusterIdentityCredentialsSecretNotAvailableV1Beta2Reason = "SecretNotAvailable"

// VSphereClusterIdentityCredentialsAvailableV1Beta2Reason surfaces when the VSphereClusterIdentity secret is already in use.
VSphereClusterIdentityCredentialsSecretAlreadyInUseV1Beta2Reason = "SecretAlreadyInUse"

// VSphereClusterIdentityCredentialsAvailableV1Beta2Reason surfaces when setting the owner reference on the VSphereClusterIdentity secret failed.
VSphereClusterIdentityCredentialsSecretOwnerReferenceFailedV1Beta2Reason = "SecretOwnerReferenceFailed"

// VSphereClusterIdentityCredentialsDeletingV1Beta2Reason surfaces when the credentials for a VSphereClusterIdentity are being deleted.
VSphereClusterIdentityCredentialsDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
)

// VSphereClusterIdentitySpec contains a secret reference and a group of allowed namespaces.
type VSphereClusterIdentitySpec struct {
// SecretName references a Secret inside the controller namespace with the credentials to use
Expand Down
99 changes: 98 additions & 1 deletion apis/v1beta1/vspheredeploymentzone_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,103 @@ const (
DeploymentZoneFinalizer = "vspheredeploymentzone.infrastructure.cluster.x-k8s.io"
)

// VSphereDeploymentZone's Ready condition and corresponding reasons that will be used in v1Beta2 API version.
const (
// VSphereDeploymentZoneReadyV1Beta2Condition is true if the VSphereDeploymentZone's deletionTimestamp is not set, VSphereDeploymentZone's
// VCenterAvailable, PlacementConstraintReady and FailureDomainValidated conditions are true.
VSphereDeploymentZoneReadyV1Beta2Condition = clusterv1.ReadyV1Beta2Condition

// VSphereDeploymentZoneReadyV1Beta2Reason surfaces when the VSphereDeploymentZone readiness criteria is met.
VSphereDeploymentZoneReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason

// VSphereDeploymentZoneNotReadyV1Beta2Reason surfaces when the VSphereDeploymentZone readiness criteria is not met.
VSphereDeploymentZoneNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason

// VSphereDeploymentZoneReadyUnknownV1Beta2Reason surfaces when at least one VSphereDeploymentZone readiness criteria is unknown
// and no VSphereDeploymentZone readiness criteria is not met.
VSphereDeploymentZoneReadyUnknownV1Beta2Reason = clusterv1.ReadyUnknownV1Beta2Reason
)

// VSphereDeploymentZone's VCenterAvailable condition and corresponding reasons that will be used in v1Beta2 API version.
const (
// VSphereDeploymentZoneVCenterAvailableV1Beta2Condition documents the status of vCenter for a VSphereDeploymentZone.
VSphereDeploymentZoneVCenterAvailableV1Beta2Condition = "VCenterAvailable"

// VSphereDeploymentZoneVCenterAvailableV1Beta2Reason surfaces when the vCenter for a VSphereDeploymentZone is available.
VSphereDeploymentZoneVCenterAvailableV1Beta2Reason = clusterv1.AvailableV1Beta2Reason

// VSphereDeploymentZoneVCenterUnreachableV1Beta2Reason surfaces when the vCenter for a VSphereDeploymentZone is unreachable.
VSphereDeploymentZoneVCenterUnreachableV1Beta2Reason = "VCenterUnreachable"

// VSphereDeploymentZoneVCenterAvailableDeletingV1Beta2Reason surfaces when the vCenter for a VSphereDeploymentZone is being deleted.
VSphereDeploymentZoneVCenterAvailableDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
)
Comment on lines +48 to +61
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in #3406 I have Available and NotAvailable as reasons for the VCenterAvalable condition on VSphereVM, wondering if we should align


// VSphereDeploymentZone's PlacementConstraintReady condition and corresponding reasons that will be used in v1Beta2 API version.
const (
// VSphereDeploymentZonePlacementConstraintReadyV1Beta2Condition documents the placement constraint status for a VSphereDeploymentZone.
VSphereDeploymentZonePlacementConstraintReadyV1Beta2Condition = "PlacementConstraintReady"

// VSphereDeploymentZonePlacementConstraintReadyV1Beta2Reason surfaces when the placement status for a VSphereDeploymentZone is ready.
VSphereDeploymentZonePlacementConstraintReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason

// VSphereDeploymentZonePlacementConstraintVCenterNotAvailableV1Beta2Reason surfaces when the placement constraint for a VSphereDeploymentZone
// can't be verified because of no connectivity to VCenter.
VSphereDeploymentZonePlacementConstraintVCenterNotAvailableV1Beta2Reason = "VCenterNotAvailable"

// VSphereDeploymentZonePlacementConstraintResourcePoolNotFoundV1Beta2Reason surfaces when the resource pool for a VSphereDeploymentZone is not found.
VSphereDeploymentZonePlacementConstraintResourcePoolNotFoundV1Beta2Reason = "ResourcePoolNotFound"

// VSphereDeploymentZonePlacementConstraintFolderNotFoundV1Beta2Reason surfaces when the resource pool for a VSphereDeploymentZone is not found.
VSphereDeploymentZonePlacementConstraintFolderNotFoundV1Beta2Reason = "FolderNotFound"

// VSphereDeploymentZonePlacementConstraintDeletingV1Beta2Reason surfaces when the VSphereDeploymentZone is being deleted.
VSphereDeploymentZonePlacementConstraintDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
)

// VSphereDeploymentZone's FailureDomainValidated condition and corresponding reasons that will be used in v1Beta2 API version.
const (
// VSphereDeploymentZoneFailureDomainValidatedV1Beta2Condition documents failure domain validation status for a VSphereDeploymentZone.
VSphereDeploymentZoneFailureDomainValidatedV1Beta2Condition = "FailureDomainValidated"

// VSphereDeploymentZoneFailureDomainValidatedV1Beta2Reason surfaces when the failure domain for a VSphereDeploymentZone is validated.
VSphereDeploymentZoneFailureDomainValidatedV1Beta2Reason = "Validated"

// VSphereDeploymentZoneFailureDomainVCenterNotAvailableV1Beta2Reason surfaces when the failure domain for a VSphereDeploymentZone
// can't be validated because of no connectivity to VCenter.
VSphereDeploymentZoneFailureDomainVCenterNotAvailableV1Beta2Reason = "VCenterNotAvailable"

// VSphereDeploymentZoneFailureDomainValidationFailedV1Beta2Reason surfaces when the failure domain's validation for a VSphereDeploymentZone failed.
VSphereDeploymentZoneFailureDomainValidationFailedV1Beta2Reason = "ValidationFailed"

// VSphereDeploymentZoneFailureDomainRegionMisconfiguredV1Beta2Reason surfaces when the failure domain's region for a VSphereDeploymentZone is misconfigured.
VSphereDeploymentZoneFailureDomainRegionMisconfiguredV1Beta2Reason = "RegionMisconfigured"

// VSphereDeploymentZoneFailureDomainZoneMisconfiguredV1Beta2Reason surfaces when the failure domain's zone for a VSphereDeploymentZone is misconfigured.
VSphereDeploymentZoneFailureDomainZoneMisconfiguredV1Beta2Reason = "ZoneMisconfigured"

// VSphereDeploymentZoneFailureDomainZoneMisconfiguredV1Beta2Reason surfaces when the failure domain's hosts for a VSphereDeploymentZone are misconfigured.
VSphereDeploymentZoneFailureDomainHostsMisconfiguredV1Beta2Reason = "HostsMisconfigured"

// VSphereDeploymentZoneFailureDomainHostsAffinityMisconfiguredV1Beta2Reason surfaces when the failure domain's hosts for a VSphereDeploymentZone are misconfigured.
VSphereDeploymentZoneFailureDomainHostsAffinityMisconfiguredV1Beta2Reason = "HostsAffinityMisconfigured"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last one, unused


// VSphereDeploymentZoneFailureDomainZoneMisconfiguredV1Beta2Reason surfaces when the failure domain's datastore for a VSphereDeploymentZone is not found.
VSphereDeploymentZoneFailureDomainDatastoreNotFoundV1Beta2Reason = "DatastoreNotFound"

// VSphereDeploymentZoneFailureDomainZoneMisconfiguredV1Beta2Reason surfaces when the failure domain's network for a VSphereDeploymentZone is not found.
VSphereDeploymentZoneFailureDomainNetworkNotFoundV1Beta2Reason = "NetworkNotFound"

// VSphereDeploymentZoneFailureDomainComputeClusterNotFoundV1Beta2Reason surfaces when the failure domain's compute cluster for a VSphereDeploymentZone failed.
VSphereDeploymentZoneFailureDomainComputeClusterNotFoundV1Beta2Reason = "ComputeClusterNotFound"

// VSphereDeploymentZoneFailureDomainValidationFailedV1Beta2Reason surfaces when the failure domain's resource pool for a VSphereDeploymentZone failed.
VSphereDeploymentZoneFailureDomainResourcePoolNotFoundV1Beta2Reason = "ResourcePoolNotFound"

// VSphereDeploymentZoneFailureDomainDeletingV1Beta2Reason surfaces when the VSphereDeploymentZone is being deleted.
VSphereDeploymentZoneFailureDomainDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
)

// VSphereDeploymentZoneSpec defines the desired state of VSphereDeploymentZone.
type VSphereDeploymentZoneSpec struct {

Expand Down Expand Up @@ -93,7 +190,7 @@ type VSphereDeploymentZoneStatus struct {
// See https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20240916-improve-status-in-CAPI-resources.md for more context.
type VSphereDeploymentZoneV1Beta2Status struct {
// conditions represents the observations of a VSphereDeploymentZone's current state.
// Known condition types are Paused.
// Known condition types are Ready, VCenterAvailable, PlacementConstraintReady, FailureDomainValidated and Paused.
// +optional
// +listType=map
// +listMapKey=type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ spec:
conditions:
description: |-
conditions represents the observations of a VSphereDeploymentZone's current state.
Known condition types are Paused.
Known condition types are Ready, VCenterAvailable, PlacementConstraintReady, FailureDomainValidated and Paused.
items:
description: Condition contains details for one aspect of the
current state of this API Resource.
Expand Down
33 changes: 33 additions & 0 deletions controllers/vsphereclusteridentity_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
clusterutilv1 "sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/conditions"
v1beta2conditions "sigs.k8s.io/cluster-api/util/conditions/v1beta2"
"sigs.k8s.io/cluster-api/util/finalizers"
"sigs.k8s.io/cluster-api/util/patch"
"sigs.k8s.io/cluster-api/util/paused"
Expand Down Expand Up @@ -102,6 +103,7 @@ func (r clusterIdentityReconciler) Reconcile(ctx context.Context, req reconcile.

if err := patchHelper.Patch(ctx, identity, patch.WithOwnedV1Beta2Conditions{Conditions: []string{
clusterv1.PausedV1Beta2Condition,
infrav1.VSphereClusterIdentityCredentialsAvailableV1Beta2Condition,
}}); err != nil {
reterr = kerrors.NewAggregate([]error{reterr, err})
}
Expand All @@ -119,12 +121,24 @@ func (r clusterIdentityReconciler) Reconcile(ctx context.Context, req reconcile.
}
if err := r.Client.Get(ctx, secretKey, secret); err != nil {
conditions.MarkFalse(identity, infrav1.CredentialsAvailableCondidtion, infrav1.SecretNotAvailableReason, clusterv1.ConditionSeverityWarning, err.Error())
v1beta2conditions.Set(identity, metav1.Condition{
Type: infrav1.VSphereClusterIdentityCredentialsAvailableV1Beta2Condition,
Status: metav1.ConditionFalse,
Reason: infrav1.VSphereClusterIdentityCredentialsSecretNotAvailableV1Beta2Reason,
Message: err.Error(),
})
return reconcile.Result{}, errors.Wrapf(err, "failed to get Secret %s", klog.KRef(secretKey.Namespace, secretKey.Name))
}

// If this secret is owned by a different VSphereClusterIdentity or a VSphereCluster, mark the identity as not ready and return an error.
if !clusterutilv1.IsOwnedByObject(secret, identity) && pkgidentity.IsOwnedByIdentityOrCluster(secret.GetOwnerReferences()) {
conditions.MarkFalse(identity, infrav1.CredentialsAvailableCondidtion, infrav1.SecretAlreadyInUseReason, clusterv1.ConditionSeverityError, "secret being used by another Cluster/VSphereIdentity")
v1beta2conditions.Set(identity, metav1.Condition{
Type: infrav1.VSphereClusterIdentityCredentialsAvailableV1Beta2Condition,
Status: metav1.ConditionFalse,
Reason: infrav1.VSphereClusterIdentityCredentialsSecretAlreadyInUseV1Beta2Reason,
Message: "secret being used by another Cluster/VSphereIdentity",
})
identity.Status.Ready = false
return reconcile.Result{}, errors.New("secret being used by another Cluster/VSphereIdentity")
}
Expand All @@ -145,10 +159,22 @@ func (r clusterIdentityReconciler) Reconcile(ctx context.Context, req reconcile.
err = r.Client.Update(ctx, secret)
if err != nil {
conditions.MarkFalse(identity, infrav1.CredentialsAvailableCondidtion, infrav1.SecretOwnerReferenceFailedReason, clusterv1.ConditionSeverityWarning, err.Error())
v1beta2conditions.Set(identity, metav1.Condition{
Type: infrav1.VSphereClusterIdentityCredentialsAvailableV1Beta2Condition,
Status: metav1.ConditionFalse,
Reason: infrav1.VSphereClusterIdentityCredentialsSecretOwnerReferenceFailedV1Beta2Reason,
Message: err.Error(),
})
return reconcile.Result{}, err
}

conditions.MarkTrue(identity, infrav1.CredentialsAvailableCondidtion)
v1beta2conditions.Set(identity, metav1.Condition{
Type: infrav1.VSphereClusterIdentityCredentialsAvailableV1Beta2Condition,
Status: metav1.ConditionTrue,
Reason: infrav1.VSphereClusterIdentityCredentialsAvailableV1Beta2Reason,
})

identity.Status.Ready = true
return reconcile.Result{}, nil
}
Expand All @@ -160,6 +186,13 @@ func (r clusterIdentityReconciler) reconcileDelete(ctx context.Context, identity
Namespace: r.ControllerManagerCtx.Namespace,
Name: identity.Spec.SecretName,
}

v1beta2conditions.Set(identity, metav1.Condition{
Type: infrav1.VSphereClusterIdentityCredentialsAvailableV1Beta2Condition,
Status: metav1.ConditionFalse,
Reason: infrav1.VSphereClusterIdentityCredentialsDeletingV1Beta2Reason,
})

err := r.Client.Get(ctx, secretKey, secret)
if err != nil {
if apierrors.IsNotFound(err) {
Expand Down
Loading
Loading