diff --git a/internal/controller/cluster_controller.go b/internal/controller/cluster_controller.go index 3eb42969..28fc30aa 100644 --- a/internal/controller/cluster_controller.go +++ b/internal/controller/cluster_controller.go @@ -18,6 +18,8 @@ package controller import ( "context" + "crypto/sha512" + "encoding/hex" "time" "github.com/giantswarm/microerror" @@ -36,10 +38,11 @@ import ( // ClusterReconciler reconciles a Cluster object type ClusterReconciler struct { - Client client.Client - Log logr.Logger - Scheme *runtime.Scheme - Teleport *teleport.Teleport + Client client.Client + Log logr.Logger + Scheme *runtime.Scheme + Teleport *teleport.Teleport + Namespace string } //+kubebuilder:rbac:groups=cluster.x-k8s.io.giantswarm.io,resources=clusters,verbs=get;list;watch;create;update;patch;delete @@ -68,6 +71,32 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct } log.Info("Reconciling cluster", "cluster", cluster) + now := time.Now() + diff := now.Sub(r.Teleport.SecretConfig.LastRead) + seconds := diff.Seconds() + minutes := seconds / 60 + hasher := sha512.New() + hasher.Write([]byte(r.Teleport.SecretConfig.IdentityFile)) + sum := hasher.Sum(nil) + hashString := hex.EncodeToString(sum) + + log.Info("Teleport identity", "last-read-minutes-ago", minutes, "hash", hashString) + + if time.Since(r.Teleport.SecretConfig.LastRead) > 1*time.Minute { + log.Info("Retrieving new identity", "secretName", key.TeleportBotSecretName) + + newSecretConfig, err := teleport.GetConfigFromSecret(ctx, r.Client, r.Namespace) + if err != nil { + return ctrl.Result{}, microerror.Mask(err) + } + r.Teleport.SecretConfig = newSecretConfig + + if r.Teleport.TeleportClient, err = teleport.NewClient(ctx, newSecretConfig.ProxyAddr, newSecretConfig.IdentityFile); err != nil { + return ctrl.Result{}, microerror.Mask(err) + } + log.Info("Re-connected to teleport cluster with new identity", "proxyAddr", newSecretConfig.ProxyAddr) + } + registerName := cluster.Name if cluster.Name != r.Teleport.SecretConfig.ManagementClusterName { registerName = key.GetRegisterName(r.Teleport.SecretConfig.ManagementClusterName, cluster.Name) diff --git a/internal/controller/cluster_controller_test.go b/internal/controller/cluster_controller_test.go index 9f29b02a..0a954f1b 100644 --- a/internal/controller/cluster_controller_test.go +++ b/internal/controller/cluster_controller_test.go @@ -101,10 +101,11 @@ func Test_ClusterController(t *testing.T) { log := ctrl.Log.WithName("test") controller := &ClusterReconciler{ - Client: ctrlClient, - Log: log, - Scheme: scheme.Scheme, - Teleport: teleport.New(tc.namespace, tc.secretConfig, test.NewMockTokenGenerator(tc.token)), + Client: ctrlClient, + Log: log, + Scheme: scheme.Scheme, + Namespace: tc.namespace, + Teleport: teleport.New(tc.namespace, tc.secretConfig, test.NewMockTokenGenerator(tc.token)), } controller.Teleport.TeleportClient = test.NewTeleportClient(test.FakeTeleportClientConfig{ Tokens: tc.tokens, @@ -179,6 +180,7 @@ func newSecretConfig() *teleport.SecretConfig { AppName: test.AppName, AppVersion: test.AppVersion, IdentityFile: test.IdentityFileValue, + LastRead: test.LastReadValue, ManagementClusterName: test.ManagementClusterName, ProxyAddr: test.ProxyAddr, TeleportVersion: test.TeleportVersion, diff --git a/internal/pkg/teleport/secret.go b/internal/pkg/teleport/secret.go index ca0bba5e..baf09362 100644 --- a/internal/pkg/teleport/secret.go +++ b/internal/pkg/teleport/secret.go @@ -3,6 +3,7 @@ package teleport import ( "context" "fmt" + "time" "github.com/giantswarm/microerror" "github.com/go-logr/logr" @@ -17,6 +18,7 @@ import ( type SecretConfig struct { ProxyAddr string + LastRead time.Time IdentityFile string TeleportVersion string ManagementClusterName string @@ -80,6 +82,7 @@ func GetConfigFromSecret(ctx context.Context, ctrlClient client.Client, namespac return &SecretConfig{ IdentityFile: identityFile, + LastRead: time.Now(), ProxyAddr: proxyAddr, ManagementClusterName: managementClusterName, TeleportVersion: teleportVersion, diff --git a/internal/pkg/test/resources.go b/internal/pkg/test/resources.go index a06bf9a6..0bda4f7e 100644 --- a/internal/pkg/test/resources.go +++ b/internal/pkg/test/resources.go @@ -41,6 +41,8 @@ const ( ConfigMapValuesFormat = "authToken: %s\nproxyAddr: %s\nroles: kube\nkubeClusterName: %s\nteleportVersionOverride: %s" ) +var LastReadValue = time.Now() + type MockTokenGenerator struct { token string } diff --git a/main.go b/main.go index eb124be6..159b05be 100644 --- a/main.go +++ b/main.go @@ -124,10 +124,11 @@ func main() { setupLog.Info("Connected to teleport cluster", "proxyAddr", tele.SecretConfig.ProxyAddr) if err = (&controller.ClusterReconciler{ - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("Cluster"), - Scheme: mgr.GetScheme(), - Teleport: tele, + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("Cluster"), + Scheme: mgr.GetScheme(), + Teleport: tele, + Namespace: namespace, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Cluster") os.Exit(1)