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

Implement kubeconfig rotation #48

Merged
merged 40 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f91f294
adds first version of states update
Disper Sep 26, 2023
669527c
small renaming
Disper Sep 26, 2023
547a9d2
[WiP] attempt to update CR status
Disper Sep 26, 2023
b463c9d
[WiP] attempt to update CR status
Disper Sep 27, 2023
79a652e
fix linter + another take on persisting CR changes
Disper Sep 27, 2023
c6382ae
CR status are now persisted
Disper Sep 27, 2023
ee24eb2
renames persistChange to persistStatusChange
Disper Sep 27, 2023
5598c1a
small clean-up on gardenercluster CR sample
Disper Sep 27, 2023
d075d8a
Fixes to statuses implementation
akgalwas Oct 13, 2023
fa580be
Merge remote-tracking branch 'upstream/main' into controller_states3
akgalwas Oct 13, 2023
ed4135b
Minor clean up
akgalwas Oct 13, 2023
fd2cdce
Linter issue fixed
akgalwas Oct 13, 2023
d1196df
Linter issue fixed
akgalwas Oct 13, 2023
5276a36
Rotation implemented
akgalwas Oct 19, 2023
d73165f
Rotation is working
akgalwas Oct 20, 2023
defc1b5
Add some debugging info
akgalwas Oct 20, 2023
c090dc9
Refactoring, and linter
akgalwas Oct 20, 2023
a490c8f
Some logs added
akgalwas Oct 20, 2023
7f69b7f
Unit test fixe
akgalwas Oct 20, 2023
22522ee
Unit test fixe
akgalwas Oct 20, 2023
67125f0
Liiinteeer
akgalwas Oct 20, 2023
cedd615
Fixed update problem
akgalwas Oct 20, 2023
3f1a173
Linter
akgalwas Oct 20, 2023
559f34a
Attempt to fix update problem
akgalwas Oct 20, 2023
0dcff61
Changed rotation to be based on secret
akgalwas Oct 20, 2023
453ae3d
Added force rotation
akgalwas Oct 20, 2023
236192c
Implemented removing operator.kyma-project.io/force-kubeconfig-rotati…
akgalwas Oct 20, 2023
ce590b2
Added new testcases
akgalwas Oct 20, 2023
004260e
Added new testcases
akgalwas Oct 20, 2023
9e17f18
Tests refactored
akgalwas Oct 20, 2023
4af62b7
Refactoring
akgalwas Oct 23, 2023
f543d06
Logging improvements
akgalwas Oct 23, 2023
2fe0263
Linter
akgalwas Oct 23, 2023
753d715
Changes to logging
akgalwas Oct 24, 2023
fd8a910
Changes to logging
akgalwas Oct 24, 2023
13bf8dc
Changes to logging
akgalwas Oct 24, 2023
732f400
Changes to statuses
akgalwas Oct 24, 2023
b780cd7
Setting status message fixed
akgalwas Oct 24, 2023
1d42b16
Changed operations order: setting status is the last operation.
akgalwas Oct 24, 2023
0e0d1bc
Fix in rotation problem.
akgalwas Oct 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 70 additions & 4 deletions api/v1/gardenercluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ limitations under the License.
package v1

import (
"fmt"

"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -67,10 +70,25 @@ type Secret struct {
type State string

const (
ReadyState State = "Ready"
ProcessingState State = "Processing"
ErrorState State = "Error"
DeletingState State = "Deleting"
ReadyState State = "Ready"
ErrorState State = "Error"
)

type ConditionReason string

const (
ConditionReasonKubeconfigSecretCreated ConditionReason = "KubeconfigSecretCreated"
ConditionReasonKubeconfigSecretRotated ConditionReason = "KubeconfigSecretRotated"
ConditionReasonFailedToGetSecret ConditionReason = "FailedToCheckSecret"
ConditionReasonFailedToCreateSecret ConditionReason = "ConditionReasonFailedToCreateSecret"
ConditionReasonFailedToUpdateSecret ConditionReason = "FailedToUpdateSecret"
ConditionReasonFailedToGetKubeconfig ConditionReason = "FailedToGetKubeconfig"
)

type ConditionType string

const (
ConditionTypeKubeconfigManagement ConditionType = "KubeconfigManagement"
)

// GardenerClusterStatus defines the observed state of GardenerCluster
Expand All @@ -86,6 +104,54 @@ type GardenerClusterStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

func (cluster *GardenerCluster) UpdateConditionForReadyState(conditionType ConditionType, reason ConditionReason, conditionStatus metav1.ConditionStatus) {
cluster.Status.State = ReadyState

condition := metav1.Condition{
Type: string(conditionType),
Status: conditionStatus,
LastTransitionTime: metav1.Now(),
Reason: string(reason),
Message: getMessage(reason),
}
meta.RemoveStatusCondition(&cluster.Status.Conditions, condition.Type)
meta.SetStatusCondition(&cluster.Status.Conditions, condition)
}

func (cluster *GardenerCluster) UpdateConditionForErrorState(conditionType ConditionType, reason ConditionReason, conditionStatus metav1.ConditionStatus, error error) {
cluster.Status.State = ErrorState

condition := metav1.Condition{
Type: string(conditionType),
Status: conditionStatus,
LastTransitionTime: metav1.Now(),
Reason: string(reason),
Message: fmt.Sprintf("%s Error: %s", getMessage(reason), error.Error()),
}
meta.RemoveStatusCondition(&cluster.Status.Conditions, condition.Type)
meta.SetStatusCondition(&cluster.Status.Conditions, condition)
}

func getMessage(reason ConditionReason) string {
switch reason {
case ConditionReasonKubeconfigSecretCreated:
return "Secret created successfully."
case ConditionReasonKubeconfigSecretRotated:
return "Secret rotated successfully."
case ConditionReasonFailedToCreateSecret:
return "Failed to create secret."
case ConditionReasonFailedToUpdateSecret:
return "Failed to rotate secret."
case ConditionReasonFailedToGetSecret:
return "Failed to get secret."
case ConditionReasonFailedToGetKubeconfig:
return "Failed to get kubeconfig."

default:
return "Unknown condition"
}
}

func init() {
SchemeBuilder.Register(&GardenerCluster{}, &GardenerClusterList{})
}
16 changes: 10 additions & 6 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

// The ratio determines what is the minimal time that needs to pass to rotate certificate.
const minimalRotationTimeRatio = 0.6

var (
scheme = runtime.NewScheme() //nolint:gochecknoglobals
setupLog = ctrl.Log.WithName("setup") //nolint:gochecknoglobals
Expand Down Expand Up @@ -106,15 +109,15 @@ func main() {
}

gardenerNamespace := fmt.Sprintf("garden-%s", gardenerProjectName)
expirationInSeconds := int64(expirationTime.Seconds())
kubeconfigProvider, err := setupKubernetesKubeconfigProvider(gardenerKubeconfigPath, gardenerNamespace, expirationInSeconds)
kubeconfigProvider, err := setupKubernetesKubeconfigProvider(gardenerKubeconfigPath, gardenerNamespace, expirationTime)

if err != nil {
setupLog.Error(err, "unable to initialize kubeconfig provider", "controller", "GardenerCluster")
os.Exit(1)
}

if err = (controller.NewGardenerClusterController(mgr, kubeconfigProvider, logger)).SetupWithManager(mgr); err != nil {
rotationPeriod := time.Duration(minimalRotationTimeRatio*expirationTime.Minutes()) * time.Minute
if err = (controller.NewGardenerClusterController(mgr, kubeconfigProvider, logger, rotationPeriod)).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "GardenerCluster")
os.Exit(1)
}
Expand All @@ -129,14 +132,15 @@ func main() {
os.Exit(1)
}

setupLog.Info("starting manager")
setupLog.Info("Starting Manager", "kubeconfigExpirationTime", expirationTime, "kubeconfigRotationPeriod", rotationPeriod)

if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
}

func setupKubernetesKubeconfigProvider(kubeconfigPath string, namespace string, expirationInSeconds int64) (gardener.KubeconfigProvider, error) {
func setupKubernetesKubeconfigProvider(kubeconfigPath string, namespace string, expirationTime time.Duration) (gardener.KubeconfigProvider, error) {
restConfig, err := gardener.NewRestConfigFromFile(kubeconfigPath)
if err != nil {
return gardener.KubeconfigProvider{}, err
Expand All @@ -163,5 +167,5 @@ func setupKubernetesKubeconfigProvider(kubeconfigPath string, namespace string,
return gardener.NewKubeconfigProvider(shootClient,
dynamicKubeconfigAPI,
namespace,
expirationInSeconds), nil
int64(expirationTime.Seconds())), nil
}
6 changes: 6 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ rules:
- gardenerclusters/finalizers
verbs:
- update
- apiGroups:
- infrastructuremanager.kyma-project.io
resources:
- gardenerclusters/status
verbs:
- update
Loading
Loading