mirror of
https://github.com/rancher/k3k.git
synced 2026-08-19 04:16:16 +00:00
129 lines
3.4 KiB
Go
129 lines
3.4 KiB
Go
package cluster
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
"github.com/rancher/k3k/pkg/apis/k3k.io/v1beta1"
|
|
)
|
|
|
|
func Test_validate(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
clusterName string
|
|
mode v1beta1.ClusterMode
|
|
tlsSANs []string
|
|
expose *v1beta1.ExposeConfig
|
|
policy *v1beta1.VirtualClusterPolicy
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "valid cluster without a policy",
|
|
},
|
|
{
|
|
name: "valid cluster with a policy",
|
|
policy: newTestPolicy(v1beta1.SharedClusterMode),
|
|
},
|
|
{
|
|
// the name check does not depend on the policy, so it also runs
|
|
// in namespaces that are not bound to one
|
|
name: "invalid cluster name without a policy",
|
|
clusterName: ClusterInvalidName,
|
|
wantErr: "invalid cluster name",
|
|
},
|
|
{
|
|
name: "invalid cluster name with a policy",
|
|
clusterName: ClusterInvalidName,
|
|
policy: newTestPolicy(v1beta1.SharedClusterMode),
|
|
wantErr: "invalid cluster name",
|
|
},
|
|
{
|
|
name: "mode not allowed by the policy",
|
|
mode: v1beta1.VirtualClusterMode,
|
|
policy: newTestPolicy(v1beta1.SharedClusterMode),
|
|
wantErr: "is not allowed by the policy",
|
|
},
|
|
{
|
|
// without a policy there is no allowed mode to check against
|
|
name: "any mode is allowed without a policy",
|
|
mode: v1beta1.VirtualClusterMode,
|
|
},
|
|
{
|
|
name: "expose without ingress",
|
|
expose: &v1beta1.ExposeConfig{NodePort: &v1beta1.NodePortConfig{}},
|
|
},
|
|
{
|
|
name: "expose ingress without tlsSANs",
|
|
expose: &v1beta1.ExposeConfig{Ingress: &v1beta1.IngressConfig{}},
|
|
wantErr: "spec.tlsSANs",
|
|
},
|
|
{
|
|
name: "expose ingress with only IP tlsSANs",
|
|
tlsSANs: []string{"10.0.0.5", "::1"},
|
|
expose: &v1beta1.ExposeConfig{Ingress: &v1beta1.IngressConfig{}},
|
|
wantErr: "spec.tlsSANs",
|
|
},
|
|
{
|
|
name: "expose ingress with a DNS tlsSAN",
|
|
tlsSANs: []string{"10.0.0.5", "my-cluster.example.com"},
|
|
expose: &v1beta1.ExposeConfig{Ingress: &v1beta1.IngressConfig{}},
|
|
},
|
|
{
|
|
name: "no ingress, IP-only tlsSANs is fine",
|
|
tlsSANs: []string{"10.0.0.5"},
|
|
expose: &v1beta1.ExposeConfig{LoadBalancer: &v1beta1.LoadBalancerConfig{}},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
clusterName := tt.clusterName
|
|
if clusterName == "" {
|
|
clusterName = "test-cluster"
|
|
}
|
|
|
|
mode := tt.mode
|
|
if mode == "" {
|
|
mode = v1beta1.SharedClusterMode
|
|
}
|
|
|
|
cluster := &v1beta1.Cluster{
|
|
ObjectMeta: metav1.ObjectMeta{Name: clusterName, Namespace: "test-namespace"},
|
|
Spec: v1beta1.ClusterSpec{
|
|
Mode: mode,
|
|
TLSSANs: tt.tlsSANs,
|
|
Expose: tt.expose,
|
|
},
|
|
}
|
|
|
|
// the Client is only needed to validate the customCAs secrets,
|
|
// which none of these clusters enable
|
|
reconciler := &ClusterReconciler{}
|
|
|
|
err := reconciler.validate(cluster, tt.policy)
|
|
|
|
if tt.wantErr == "" {
|
|
assert.NoError(t, err)
|
|
return
|
|
}
|
|
|
|
assert.Error(t, err)
|
|
// the status controller relies on this to report Pending/ValidationFailed
|
|
// instead of letting the API server reject an invalid resource.
|
|
assert.True(t, errors.Is(err, ErrClusterValidation))
|
|
assert.Contains(t, err.Error(), tt.wantErr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func newTestPolicy(allowedMode v1beta1.ClusterMode) *v1beta1.VirtualClusterPolicy {
|
|
return &v1beta1.VirtualClusterPolicy{
|
|
ObjectMeta: metav1.ObjectMeta{Name: "test-policy"},
|
|
Spec: v1beta1.VirtualClusterPolicySpec{AllowedMode: allowedMode},
|
|
}
|
|
}
|