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

feat: making control plane endpoint fields optional #106

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

prometherion
Copy link

Issue #95

Description of changes:

Skipping webhook validation for the ProxmoxCluster Control Plane endpoint field.

The ProxmoxCluster controller will wait for a valid IP before proceeding to mark the infrastructure ready.

Testing performed:

N.A.

Copy link

sonarcloud bot commented Feb 9, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
20.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarCloud

@prometherion
Copy link
Author

Before providing more test coverage, may I ask for a simple review of the proposed changes, from a workflow perspective?

It's not clear to me if the maintainers are open to skipping the validation of the ProxmoxCluster.spec.controlPlaneEnpdoint field.

@avorima
Copy link
Collaborator

avorima commented Feb 19, 2024

Hi @prometherion, thank you for your contribution. Skipping validation for optional fields is fine, but please make sure your changes don't alter the validation behavior of other fields. Users should see errors as early as possible.
The controller checks for empty control plane endpoint should be done after IPAM was reconciled, so that they're not waiting for the external process to set the control plane endpoint.

Does Kamaji set the port and address separately? I'm asking, because my understanding was that the endpoint is always written in full or not at all. This would mean that you could merge the two conditions into one MissingControlPlaneEndpoint.

@wikkyk wikkyk added this to the v0.4.0 milestone Feb 22, 2024
@prometherion
Copy link
Author

Does Kamaji set the port and address separately?

Kamaji is doing in a single transaction, yes, I can uniform those checks.

@mcbenjemaa
Copy link
Member

Anything needed here?

@prometherion
Copy link
Author

Thanks for the heads up @mcbenjemaa, I'm planning to work on this to make the PR ready for review, by the end of the week or the following one.

Pretty busy days, sorry.

@mcbenjemaa
Copy link
Member

take your time mate

@mcbenjemaa
Copy link
Member

@prometherion
Are there any updates on this, or can I try it

@prometherion
Copy link
Author

Finally, I'm revamping it, feeling sorry for being late @mcbenjemaa.

Let me know if we're ready to get this tested.

@mcbenjemaa
Copy link
Member

can you provide a use-case to test it with Kamaji?

Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
Copy link

sonarcloud bot commented Jun 7, 2024

Copy link
Collaborator

@wikkyk wikkyk left a comment

Choose a reason for hiding this comment

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

I think this is close to done. The core is there but I'm not sold on the details.. This could use some test cases which would've uncovered the inconsistency I pointed out inline.

However, I don't think I like the 'magic' behaviour of empty host and(?) port meaning externally managed. Someone could omit host/port by accident without actually intending to use Kamaji or so. This needs very clear documentation. (Technically, this doesn't actually make the fields optional (-:)

Personally, I would prefer an optional bool field in ProxmoxClusterSpec like ControlPlaneEndpointExternallyManaged and to require that either ControlPlaneEndpointExternallyManaged or ControlPlaneEndpoint is set. This would make the intent clear.

That said, I would be fine with just clearly, explicitly documenting that setting host="" and port=0 means we'll wait for an externally managed endpoint. The check in proxmoxcluster_controller.go would need to be exactly the same as in the validation func i.e. host=="" && port==0.

Comment on lines -27 to +35
infrav1 "github.com/ionos-cloud/cluster-api-provider-proxmox/api/v1alpha1"
"github.com/pkg/errors"
"go4.org/netipx"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

infrav1 "github.com/ionos-cloud/cluster-api-provider-proxmox/api/v1alpha1"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is a spurious change.

Copy link
Author

Choose a reason for hiding this comment

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

It's my IDE sorting go imports, I'll amend it.

Comment on lines +98 to +102
// Skipping the validation of the Control Plane endpoint in case of an empty value:
// this is the case of externally managed Control Plane which eventually provides the LB.
if ep.Host == "" && ep.Port == 0 {
return nil
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

What about the case where someone accidentally doesn't provide the control plane endpoint?

@@ -94,6 +95,11 @@ func (*ProxmoxCluster) ValidateUpdate(_ context.Context, _ runtime.Object, newOb

func validateControlPlaneEndpoint(cluster *infrav1.ProxmoxCluster) error {
ep := cluster.Spec.ControlPlaneEndpoint
// Skipping the validation of the Control Plane endpoint in case of an empty value:
// this is the case of externally managed Control Plane which eventually provides the LB.
if ep.Host == "" && ep.Port == 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could use some test cases.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, default Port is 6443.

@@ -168,6 +168,22 @@ func (r *ProxmoxClusterReconciler) reconcileNormal(ctx context.Context, clusterS
// If the ProxmoxCluster doesn't have our finalizer, add it.
ctrlutil.AddFinalizer(clusterScope.ProxmoxCluster, infrav1alpha1.ClusterFinalizer)

cpe := clusterScope.ControlPlaneEndpoint()
switch {
case cpe.Host == "":
Copy link
Collaborator

Choose a reason for hiding this comment

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

This only checks host but not port, yet the validation func checks both.

@wikkyk wikkyk added this to the v0.6.0 milestone Jun 10, 2024
@prometherion
Copy link
Author

However, I don't think I like the 'magic' behaviour of empty host and(?) port meaning externally managed. Someone could omit host/port by accident without actually intending to use Kamaji or so. This needs very clear documentation. (Technically, this doesn't actually make the fields optional (-:)

Documentation is a great place, of course, wondering if we could implement this kind of check in a different way.

The Cluster API has a contract for an externally managed control plane thanks to the status key externalManagedControlPlane.

When a user is open to using Kamaji, or any other Control Plane provider which is satisfying that status key contract, we could skip the validation requiring a filled ControlPlaneEndpoint struct. With this, we're creating more guardrails for users that otherwise could shoot themselves in the foot.

@wikkyk
Copy link
Collaborator

wikkyk commented Jun 11, 2024

Two points, then:

  1. We should set externalManagedControlPlane in the status when selected
  2. I like it when things are explicit (or I don't like magic values) so I'd opt for a new key in ProxmoxClusterSpec (we can name it ExternalManagedControlPlane to stay consistent) and the user either sets it to true or populates ControlPlaneEndpoint and we validate that only one of those is set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants