Skip to content

Commit

Permalink
feat: added unit tests and renaming
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Case <[email protected]>
  • Loading branch information
richardcase committed Oct 6, 2023
1 parent 22d7324 commit 6ba5cd0
Show file tree
Hide file tree
Showing 14 changed files with 515 additions and 36 deletions.
1 change: 1 addition & 0 deletions charts/rancher-turtles/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ spec:
containers:
- args:
- --leader-elect
- --feature-gates=rancher-kube-secret-patch={{ .Values.rancherTurtles.rancher-kubeconfigs.label }}
{{- range .Values.rancherTurtles.managerArguments }}
- {{ . }}
{{- end }}
Expand Down
3 changes: 3 additions & 0 deletions charts/rancher-turtles/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ rancherTurtles:
namespace: rancher-turtles-system
managerArguments: {}
imagePullSecrets: []
features:
rancher-kubeconfigs:
label: true
cluster-api-operator:
enabled: true
cert-manager:
Expand Down
12 changes: 12 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ rules:
- patch
- update
- watch
- apiGroups:
- ""
resources:
- events
- secrets
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
Expand Down
12 changes: 6 additions & 6 deletions feature/feature.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package feature

import (
"k8s.io/apimachinery/pkg/util/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/component-base/featuregate"
)

const (
// V2ProvKcfgPatch is used to enable patching of the v2prov created kubeconfig secrets so that they
// can be used with CAPI 1.5.x.
V2ProvKcfgPatch featuregate.Feature = "V2ProvKcfgPatch"
// RancherKubeSecretPatch is used to enable patching of the Rancher v2prov created kubeconfig
// secrets so that they can be used with CAPI 1.5.x.
RancherKubeSecretPatch featuregate.Feature = "rancher-kube-secret-patch" //nolint:gosec
)

func init() {
runtime.Must(MutableGates.Add(defaultGates))
utilruntime.Must(MutableGates.Add(defaultGates))
}

var defaultGates = map[featuregate.Feature]featuregate.FeatureSpec{
V2ProvKcfgPatch: {Default: false, PreRelease: featuregate.Beta},
RancherKubeSecretPatch: {Default: false, PreRelease: featuregate.Beta},
}
5 changes: 3 additions & 2 deletions feature/gates.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package feature

import (
"k8s.io/component-base/featuregate"

"sigs.k8s.io/cluster-api/feature"
)

var (
// MutableGates is a mutable version of DefaultFeatureGate.
// Only top-level commands/options setup and the k8s.io/component-base/featuregate/testing package should make use of this.
// Tests that need to modify featuregate gates for the duration of their test should use:
// defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.<FeatureName>, <value>)()
// Tests that need to modify featuregate gates for the duration of their test should use
// defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.<FeatureName>, <value>)().
MutableGates featuregate.MutableFeatureGate = feature.MutableGates

// Gates is a shared global FeatureGate.
Expand Down
47 changes: 25 additions & 22 deletions internal/controllers/patch_kcfg_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,29 @@ import (
"context"
"fmt"

provisioningv1 "github.com/rancher-sandbox/rancher-turtles/internal/rancher/provisioning/v1"
turtlespredicates "github.com/rancher-sandbox/rancher-turtles/util/predicates"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/retry"
capi "sigs.k8s.io/cluster-api/api/v1beta1"
"sigs.k8s.io/cluster-api/controllers/external"
"sigs.k8s.io/cluster-api/controllers/remote"
"sigs.k8s.io/cluster-api/util/predicates"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/log"

clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
"sigs.k8s.io/cluster-api/controllers/external"
"sigs.k8s.io/cluster-api/controllers/remote"
"sigs.k8s.io/cluster-api/util/predicates"

provisioningv1 "github.com/rancher-sandbox/rancher-turtles/internal/rancher/provisioning/v1"
turtlespredicates "github.com/rancher-sandbox/rancher-turtles/util/predicates"
)

type V2ProvKcfgSecretReconciler struct {
// RancherKubeconfigSecretReconciler is a controller that will reconcile secrets created by Rancher as
// part of provisioning v2. Its job is to add the label required by Cluster API v1.5.0 and higher.
type RancherKubeconfigSecretReconciler struct {
Client client.Client
RancherClient client.Client
recorder record.EventRecorder
Expand All @@ -50,7 +54,8 @@ type V2ProvKcfgSecretReconciler struct {
remoteClientGetter remote.ClusterClientGetter
}

func (r *V2ProvKcfgSecretReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
// SetupWithManager will setup the controller.
func (r *RancherKubeconfigSecretReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
log := log.FromContext(ctx)

if r.remoteClientGetter == nil {
Expand Down Expand Up @@ -86,7 +91,7 @@ func (r *V2ProvKcfgSecretReconciler) SetupWithManager(ctx context.Context, mgr c
// +kubebuilder:rbac:groups=provisioning.cattle.io,resources=clusters;clusters/status,verbs=get;list;watch

// Reconcile will patch v2prov created kubeconfig secrets to add the required owner label if its missing.
func (r *V2ProvKcfgSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, reterr error) {
func (r *RancherKubeconfigSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, reterr error) {
log := log.FromContext(ctx)
log.Info("Reconciling v2prov cluster")

Expand All @@ -99,7 +104,7 @@ func (r *V2ProvKcfgSecretReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{Requeue: true}, err
}

_, ok := secret.Labels[capi.ClusterNameLabel]
_, ok := secret.Labels[clusterv1.ClusterNameLabel]
if ok {
log.V(4).Info("kubeconfig secret %s/%s already has the capi cluster label", secret.Name, secret.Name)

Expand All @@ -122,11 +127,11 @@ func (r *V2ProvKcfgSecretReconciler) Reconcile(ctx context.Context, req ctrl.Req
if secretCopy.Labels == nil {
secretCopy.Labels = map[string]string{}
}
secretCopy.Labels[capi.ClusterNameLabel] = clusterName
secretCopy.Labels[clusterv1.ClusterNameLabel] = clusterName

patchBase := client.MergeFromWithOptions(secret.DeepCopy(), client.MergeFromWithOptimisticLock{})
patchBase := client.MergeFromWithOptions(secret, client.MergeFromWithOptimisticLock{})

if err := r.Client.Patch(ctx, secret, patchBase); err != nil {
if err := r.Client.Patch(ctx, secretCopy, patchBase); err != nil {
return fmt.Errorf("failed to patch secret: %w", err)
}

Expand All @@ -140,12 +145,12 @@ func (r *V2ProvKcfgSecretReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, nil
}

func (r *V2ProvKcfgSecretReconciler) getClusterName(ctx context.Context, secret *corev1.Secret) (string, error) {
func (r *RancherKubeconfigSecretReconciler) getClusterName(ctx context.Context, secret *corev1.Secret) (string, error) {
v2ProvClusterName := ""

for _, ref := range secret.OwnerReferences {
if ref.Kind == provisioningv1.GroupVersion.Identifier() {
if ref.Kind != "Cluster" {
if ref.APIVersion == provisioningv1.GroupVersion.Identifier() {
if ref.Kind == "Cluster" {
v2ProvClusterName = ref.Name

break
Expand All @@ -160,14 +165,12 @@ func (r *V2ProvKcfgSecretReconciler) getClusterName(ctx context.Context, secret
v2ProvCluster := &provisioningv1.Cluster{}

if err := r.Client.Get(ctx, types.NamespacedName{Name: v2ProvClusterName, Namespace: secret.Namespace}, v2ProvCluster); err != nil {
return "", fmt.Errorf("Getting v2prov cluster: %w", err)
return "", fmt.Errorf("getting rancher cluster: %w", err)
}

for _, ref := range v2ProvCluster.OwnerReferences {
if ref.Kind == "Cluster" && ref.Kind == capi.GroupVersion.Identifier() {
return ref.Name, nil
}
if v2ProvCluster.Spec.RKEConfig == nil {
return "", nil
}

return "", nil
return v2ProvCluster.Name, nil
}
Loading

0 comments on commit 6ba5cd0

Please sign in to comment.