-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: xuezhaojun <zxue@redhat.com>
- Loading branch information
1 parent
0882f6d
commit 73f58c6
Showing
19 changed files
with
1,546 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
pkg/registration/spoke/bootstrapkubeconfigsmanager/bootstrapkubeconfig.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package bootstrapkubeconfigsmanager | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/client-go/kubernetes" | ||
) | ||
|
||
type boostrapKubeConfigStatus string | ||
|
||
const ( | ||
boostrapKubeConfigStatusInValid boostrapKubeConfigStatus = "InValid" | ||
boostrapKubeConfigStatusValid boostrapKubeConfigStatus = "Valid" | ||
) | ||
|
||
// bootstrapKubeConfig represents a bootstrap kubeconfig that agent can use to bootstrap a managed cluster. | ||
type boostrapKubeConfig interface { | ||
// Name returns the name of the bootstrap kubeconfig. It helps to identify the bootstrap kubeconfig. | ||
Name() string | ||
|
||
// KubeConfigData returns the kubeconfig data of the bootstrap kubeconfig. | ||
// KubeConfigData includes the kubeconfig and the credentials to connect to the hub cluster. | ||
KubeConfigData() (map[string][]byte, error) | ||
|
||
// Status returns the status of the bootstrap kubeconfig. | ||
// A bootstrap kubeconfig has two status: Valid and InValid. | ||
Status() (boostrapKubeConfigStatus, error) | ||
|
||
// Fail means at the time t, the bootstrap kubeconfig failed to connect to the hub cluster. | ||
Fail(t time.Time) error | ||
} | ||
|
||
var _ boostrapKubeConfig = &boostrapKubeConfigSecretImpl{} | ||
|
||
const ( | ||
// BootstrapKubeconfigFailedTimeAnnotationKey represents the time when the bootstrap kubeconfig failed | ||
BootstrapKubeconfigFailedTimeAnnotationKey = "agent.open-cluster-management.io/bootstrap-kubeconfig-failed-time" | ||
) | ||
|
||
type boostrapKubeConfigSecretImpl struct { | ||
secretName string | ||
secretNamespace string | ||
skipFailedBootstrapKubeconfigSeconds int32 // if a bootstrap kubeconfig failed, in 3 mins, it can't be used in rebootstrap. | ||
kubeClient kubernetes.Interface | ||
} | ||
|
||
func (b *boostrapKubeConfigSecretImpl) Name() string { | ||
return b.secretName | ||
} | ||
|
||
func (b *boostrapKubeConfigSecretImpl) KubeConfigData() (map[string][]byte, error) { | ||
secret, err := b.kubeClient.CoreV1().Secrets(b.secretNamespace).Get(context.Background(), b.secretName, metav1.GetOptions{}) | ||
if err != nil { | ||
return nil, fmt.Errorf("get the bootstrap kubeconfig secret failed: %v", err) | ||
} | ||
return secret.Data, nil | ||
} | ||
|
||
func (b *boostrapKubeConfigSecretImpl) Status() (boostrapKubeConfigStatus, error) { | ||
secret, err := b.kubeClient.CoreV1().Secrets(b.secretNamespace).Get(context.Background(), b.secretName, metav1.GetOptions{}) | ||
if err != nil { | ||
return boostrapKubeConfigStatusInValid, fmt.Errorf("get the bootstrap kubeconfig secret failed: %v", err) | ||
} | ||
|
||
if secret.Annotations == nil { | ||
return boostrapKubeConfigStatusValid, nil | ||
} | ||
|
||
now := time.Now() | ||
if failedTime, ok := secret.Annotations[BootstrapKubeconfigFailedTimeAnnotationKey]; ok { | ||
failedTimeParsed, err := time.Parse(time.RFC3339, failedTime) | ||
if err != nil { | ||
return boostrapKubeConfigStatusInValid, fmt.Errorf("failed to parse the failed time %s of the secret %s: %v", failedTime, secret.Name, err) | ||
} | ||
if now.Sub(failedTimeParsed).Seconds() < float64(b.skipFailedBootstrapKubeconfigSeconds) { | ||
return boostrapKubeConfigStatusInValid, nil | ||
} | ||
} | ||
return boostrapKubeConfigStatusValid, nil | ||
} | ||
|
||
func (b *boostrapKubeConfigSecretImpl) Fail(t time.Time) error { | ||
secret, err := b.kubeClient.CoreV1().Secrets(b.secretNamespace).Get(context.Background(), b.secretName, metav1.GetOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("get the bootstrap kubeconfig secret failed: %v", err) | ||
} | ||
secretCopy := secret.DeepCopy() | ||
if secretCopy.Annotations == nil { | ||
secretCopy.Annotations = make(map[string]string) | ||
} | ||
secretCopy.Annotations[BootstrapKubeconfigFailedTimeAnnotationKey] = t.Format(time.RFC3339) | ||
_, err = b.kubeClient.CoreV1().Secrets(b.secretNamespace).Update(context.Background(), secretCopy, metav1.UpdateOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("update the secret %s failed: %v", b.secretName, err) | ||
} | ||
return nil | ||
} |
Oops, something went wrong.