removed hcpRegitration command

This commit is contained in:
Enrico Candino
2026-06-12 17:36:50 +02:00
parent 898b2f34f0
commit cff7141af7
8 changed files with 10 additions and 110 deletions
@@ -3173,13 +3173,6 @@ spec:
- type
type: object
type: array
hcpRegistration:
description: |-
HCPRegistration is a copy-pasteable K3s installer command that external
(BYO) nodes can run to register against an HCP-mode cluster.
Only populated when Mode is "hcp" and an externally-routable endpoint
(NodePort, LoadBalancer or Ingress) is configured.
type: string
hostVersion:
description: HostVersion is the Kubernetes version of the host node.
type: string
+1 -1
View File
@@ -54,7 +54,7 @@ k3kcli cluster create [command options] NAME
--kubeconfig-server string override the kubeconfig server host
--labels stringArray Labels to add to the cluster object (e.g. key=value)
--mirror-host-nodes Mirror Host Cluster Nodes
--mode string k3k mode type (shared, virtual) (default "shared")
--mode string k3k mode type (shared, virtual, hcp) (default "shared")
-n, --namespace string namespace of the k3k cluster
--persistence-type string persistence mode for the nodes (dynamic, ephemeral) (default "dynamic")
--policy string The policy to create the cluster in
+1 -1
View File
@@ -25,7 +25,7 @@ k3kcli cluster create [command options] NAME
--kubeconfig-server string override the kubeconfig server host
--labels stringArray Labels to add to the cluster object (e.g. key=value)
--mirror-host-nodes Mirror Host Cluster Nodes
--mode string k3k mode type (shared, virtual) (default "shared")
--mode string k3k mode type (shared, virtual, hcp) (default "shared")
-n, --namespace string namespace of the k3k cluster
--persistence-type string persistence mode for the nodes (dynamic, ephemeral) (default "dynamic")
--policy string The policy to create the cluster in
+4 -4
View File
@@ -134,7 +134,7 @@ _Underlying type:_ _string_
ClusterMode is the possible provisioning mode of a Cluster.
_Validation:_
- Enum: [shared virtual]
- Enum: [shared virtual hcp]
_Appears In:_
@@ -177,8 +177,8 @@ _Appears In:_
| *`version`* __string__ | Version is the K3s version to use for the virtual nodes. +
It should follow the K3s versioning convention (e.g., v1.28.2-k3s1). +
If not specified, the Kubernetes version of the host node will be used. + | |
| *`mode`* __xref:{anchor_prefix}-github-com-rancher-k3k-pkg-apis-k3k-io-v1beta1-clustermode[$$ClusterMode$$]__ | Mode specifies the cluster provisioning mode: "shared" or "virtual". +
Defaults to "shared". This field is immutable. + | shared | Enum: [shared virtual] +
| *`mode`* __xref:{anchor_prefix}-github-com-rancher-k3k-pkg-apis-k3k-io-v1beta1-clustermode[$$ClusterMode$$]__ | Mode specifies the cluster provisioning mode: "shared", "virtual" or "hcp". +
Defaults to "shared". This field is immutable. + | shared | Enum: [shared virtual hcp] +
| *`servers`* __integer__ | Servers specifies the number of K3s pods to run in server (control plane) mode. +
Must be at least 1. Defaults to 1. + | 1 |
@@ -790,7 +790,7 @@ to set defaults and constraints (min/max) + | |
This includes both node affinity and pod affinity/anti-affinity rules. + | |
| *`defaultAgentAffinity`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#affinity-v1-core[$$Affinity$$]__ | DefaultAgentAffinity specifies the affinity rules applied to agent pods of all clusters in the target Namespace. +
This includes both node affinity and pod affinity/anti-affinity rules. + | |
| *`allowedMode`* __xref:{anchor_prefix}-github-com-rancher-k3k-pkg-apis-k3k-io-v1beta1-clustermode[$$ClusterMode$$]__ | AllowedMode specifies the allowed cluster provisioning mode. Defaults to "shared". + | shared | Enum: [shared virtual] +
| *`allowedMode`* __xref:{anchor_prefix}-github-com-rancher-k3k-pkg-apis-k3k-io-v1beta1-clustermode[$$ClusterMode$$]__ | AllowedMode specifies the allowed cluster provisioning mode. Defaults to "shared". + | shared | Enum: [shared virtual hcp] +
| *`disableNetworkPolicy`* __boolean__ | DisableNetworkPolicy indicates whether to disable the creation of a default network policy for cluster isolation. + | |
| *`podSecurityAdmissionLevel`* __xref:{anchor_prefix}-github-com-rancher-k3k-pkg-apis-k3k-io-v1beta1-podsecurityadmissionlevel[$$PodSecurityAdmissionLevel$$]__ | PodSecurityAdmissionLevel specifies the pod security admission level applied to the pods in the namespace. + | | Enum: [privileged baseline restricted] +
+3 -3
View File
@@ -103,7 +103,7 @@ _Underlying type:_ _string_
ClusterMode is the possible provisioning mode of a Cluster.
_Validation:_
- Enum: [shared virtual]
- Enum: [shared virtual hcp]
_Appears in:_
- [ClusterSpec](#clusterspec)
@@ -138,7 +138,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `version` _string_ | Version is the K3s version to use for the virtual nodes.<br />It should follow the K3s versioning convention (e.g., v1.28.2-k3s1).<br />If not specified, the Kubernetes version of the host node will be used. | | |
| `mode` _[ClusterMode](#clustermode)_ | Mode specifies the cluster provisioning mode: "shared" or "virtual".<br />Defaults to "shared". This field is immutable. | shared | Enum: [shared virtual] <br /> |
| `mode` _[ClusterMode](#clustermode)_ | Mode specifies the cluster provisioning mode: "shared", "virtual" or "hcp".<br />Defaults to "shared". This field is immutable. | shared | Enum: [shared virtual hcp] <br /> |
| `servers` _integer_ | Servers specifies the number of K3s pods to run in server (control plane) mode.<br />Must be at least 1. Defaults to 1. | 1 | |
| `agents` _integer_ | Agents specifies the number of K3s pods to run in agent (worker) mode.<br />Must be 0 or greater. Defaults to 0.<br />This field is ignored in "shared" mode. | 0 | |
| `clusterCIDR` _string_ | ClusterCIDR is the CIDR range for pod IPs.<br />Defaults to 10.42.0.0/16 in shared mode and 10.52.0.0/16 in virtual mode.<br />This field is immutable. | | |
@@ -590,7 +590,7 @@ _Appears in:_
| `defaultPriorityClass` _string_ | DefaultPriorityClass specifies the priorityClassName applied to all pods of all clusters in the target Namespace. | | |
| `defaultServerAffinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#affinity-v1-core)_ | DefaultServerAffinity specifies the affinity rules applied to server pods of all clusters in the target Namespace.<br />This includes both node affinity and pod affinity/anti-affinity rules. | | |
| `defaultAgentAffinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#affinity-v1-core)_ | DefaultAgentAffinity specifies the affinity rules applied to agent pods of all clusters in the target Namespace.<br />This includes both node affinity and pod affinity/anti-affinity rules. | | |
| `allowedMode` _[ClusterMode](#clustermode)_ | AllowedMode specifies the allowed cluster provisioning mode. Defaults to "shared". | shared | Enum: [shared virtual] <br /> |
| `allowedMode` _[ClusterMode](#clustermode)_ | AllowedMode specifies the allowed cluster provisioning mode. Defaults to "shared". | shared | Enum: [shared virtual hcp] <br /> |
| `disableNetworkPolicy` _boolean_ | DisableNetworkPolicy indicates whether to disable the creation of a default network policy for cluster isolation. | | |
| `podSecurityAdmissionLevel` _[PodSecurityAdmissionLevel](#podsecurityadmissionlevel)_ | PodSecurityAdmissionLevel specifies the pod security admission level applied to the pods in the namespace. | | Enum: [privileged baseline restricted] <br /> |
| `sync` _[SyncConfig](#syncconfig)_ | Sync specifies the resources types that will be synced from virtual cluster to host cluster. | \{ \} | |
-8
View File
@@ -624,14 +624,6 @@ type ClusterStatus struct {
// +optional
KubeletPort int `json:"kubeletPort,omitempty"`
// HCPRegistration is a copy-pasteable K3s installer command that external
// (BYO) nodes can run to register against an HCP-mode cluster.
// Only populated when Mode is "hcp" and an externally-routable endpoint
// (NodePort, LoadBalancer or Ingress) is configured.
//
// +optional
HCPRegistration string `json:"hcpRegistration,omitempty"`
// Conditions are the individual conditions for the cluster set.
//
// +optional
+1 -23
View File
@@ -29,7 +29,7 @@ import (
func (c *ClusterReconciler) ensureHCPRegistration(ctx context.Context, cluster *v1beta1.Cluster, token string) error {
log := ctrl.LoggerFrom(ctx)
url, external, err := server.ServerURL(ctx, c.Client, cluster, selectNonLoopbackSAN(cluster), 0)
_, external, err := server.ServerURL(ctx, c.Client, cluster, selectNonLoopbackSAN(cluster), 0)
if err != nil {
return err
}
@@ -44,33 +44,11 @@ func (c *ClusterReconciler) ensureHCPRegistration(ctx context.Context, cluster *
Reason: ReasonHCPNoExternalEndpoint,
Message: "HCP cluster has no external endpoint; set spec.expose.nodePort, spec.expose.loadBalancer or spec.expose.ingress so external nodes can reach the API server",
})
cluster.Status.HCPRegistration = ""
return nil
}
version := cluster.Spec.Version
if version == "" {
version = cluster.Status.HostVersion
}
cluster.Status.HCPRegistration = hcpRegistrationCommand(version, url, token)
return nil
}
// hcpRegistrationCommand returns the standard K3s installer one-liner an
// end-user can copy onto an external host to join an HCP cluster.
func hcpRegistrationCommand(version, serverURL, token string) string {
if version == "" {
return fmt.Sprintf("curl -sfL https://get.k3s.io | K3S_URL=%s K3S_TOKEN=%s sh -", serverURL, token)
}
return fmt.Sprintf("curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=%s K3S_URL=%s K3S_TOKEN=%s sh -",
version, serverURL, token)
}
// selectNonLoopbackSAN returns the first non-loopback address from the
// cluster's TLS SANs, preferring spec.TLSSANs then falling back to status.TLSSANs.
// Returns empty string if no non-loopback address is found.
-63
View File
@@ -2,7 +2,6 @@ package cluster
import (
"context"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -19,38 +18,6 @@ import (
"github.com/rancher/k3k/pkg/controller/cluster/server"
)
func Test_hcpRegistrationCommand(t *testing.T) {
tests := []struct {
name string
version string
serverURL string
token string
want string
}{
{
name: "with version",
version: "v1.33.1-k3s1",
serverURL: "https://1.2.3.4:30443",
token: "abcd1234",
want: "curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.33.1-k3s1 K3S_URL=https://1.2.3.4:30443 K3S_TOKEN=abcd1234 sh -",
},
{
name: "without version",
version: "",
serverURL: "https://hcp.example.com",
token: "tok",
want: "curl -sfL https://get.k3s.io | K3S_URL=https://hcp.example.com K3S_TOKEN=tok sh -",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := hcpRegistrationCommand(tt.version, tt.serverURL, tt.token)
assert.Equal(t, tt.want, got)
})
}
}
func Test_ensureHCPRegistration(t *testing.T) {
scheme := runtime.NewScheme()
require.NoError(t, corev1.AddToScheme(scheme))
@@ -68,33 +35,6 @@ func Test_ensureHCPRegistration(t *testing.T) {
},
}
t.Run("nodeport service produces ready-to-copy command", func(t *testing.T) {
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: server.ServiceName(cluster.Name),
Namespace: cluster.Namespace,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeNodePort,
ClusterIP: "10.43.0.50",
Ports: []corev1.ServicePort{
{Name: "k3s-server-port", Port: 443, NodePort: 31001},
},
},
}
fakeClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(svc).Build()
r := &ClusterReconciler{Client: fakeClient}
c := cluster.DeepCopy()
require.NoError(t, r.ensureHCPRegistration(context.Background(), c, "join-token-xyz"))
assert.Contains(t, c.Status.HCPRegistration, "K3S_URL=https://hcp.example.com:31001")
assert.Contains(t, c.Status.HCPRegistration, "K3S_TOKEN=join-token-xyz")
assert.Contains(t, c.Status.HCPRegistration, "INSTALL_K3S_VERSION=v1.33.1-k3s1")
assert.True(t, strings.HasPrefix(c.Status.HCPRegistration, "curl -sfL https://get.k3s.io"))
})
t.Run("clusterip-only service sets degraded condition and clears registration", func(t *testing.T) {
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -114,11 +54,8 @@ func Test_ensureHCPRegistration(t *testing.T) {
r := &ClusterReconciler{Client: fakeClient}
c := cluster.DeepCopy()
c.Status.HCPRegistration = "stale-value"
require.NoError(t, r.ensureHCPRegistration(context.Background(), c, "ignored"))
assert.Empty(t, c.Status.HCPRegistration)
cond := meta.FindStatusCondition(c.Status.Conditions, ConditionReady)
require.NotNil(t, cond)
assert.Equal(t, metav1.ConditionFalse, cond.Status)