This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch refactor-with-go
in repository https://gitbox.apache.org/repos/asf/dubbo-admin.git


The following commit(s) were added to refs/heads/refactor-with-go by this push:
     new f31eeeab refresh signed cert (#1031)
f31eeeab is described below

commit f31eeeab743bd46b531de5248e659bd132c163f0
Author: xin gu <[email protected]>
AuthorDate: Fri Mar 17 16:15:46 2023 +0800

    refresh signed cert (#1031)
    
    * refresh signed cert
    
    * Update client.go
    
    * Update client.go
    
    * identity to options
    
    * fix test
---
 pkg/authority/config/envflag.go       | 18 ++++++++++++++
 pkg/authority/config/options.go       |  3 ++-
 pkg/authority/k8s/client.go           | 45 ++++++++++++++++++++++++++++++++++-
 pkg/authority/security/server.go      |  3 +--
 pkg/authority/security/server_test.go |  5 ++++
 5 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/pkg/authority/config/envflag.go b/pkg/authority/config/envflag.go
index d2edf91d..5e858cd8 100644
--- a/pkg/authority/config/envflag.go
+++ b/pkg/authority/config/envflag.go
@@ -16,7 +16,10 @@
 package config
 
 import (
+       "crypto/rand"
+       "encoding/base32"
        "flag"
+       "fmt"
        "os"
        "strconv"
 )
@@ -40,6 +43,7 @@ func GetOptions() *Options {
                InPodEnv:              GetBoolEnv("inpodenv", false),
                IsKubernetesConnected: GetBoolEnv("iskubernetesconnected", 
false),
                EnableOIDCCheck:       GetBoolEnv("enableoidccheck", true),
+               ResourcelockIdentity:  GetStringEnv("POD_NAME", 
GetDefaultResourcelockIdentity()),
        }
 
        flag.StringVar(&options.Namespace, "namespace", options.Namespace, 
"dubbo namespace")
@@ -95,3 +99,17 @@ func GetBoolEnv(name string, defvalue bool) bool {
                return defvalue
        }
 }
+
+func GetDefaultResourcelockIdentity() string {
+       hostname, err := os.Hostname()
+       if err != nil {
+               panic(err)
+       }
+       randomBytes := make([]byte, 5)
+       _, err = rand.Read(randomBytes)
+       if err != nil {
+               panic(err)
+       }
+       randomStr := base32.StdEncoding.EncodeToString(randomBytes)
+       return fmt.Sprintf("%s-%s", hostname, randomStr)
+}
diff --git a/pkg/authority/config/options.go b/pkg/authority/config/options.go
index e73af70a..1c8a16f2 100644
--- a/pkg/authority/config/options.go
+++ b/pkg/authority/config/options.go
@@ -32,5 +32,6 @@ type Options struct {
        InPodEnv              bool
        IsKubernetesConnected bool
 
-       EnableOIDCCheck bool
+       EnableOIDCCheck      bool
+       ResourcelockIdentity string
 }
diff --git a/pkg/authority/k8s/client.go b/pkg/authority/k8s/client.go
index 18f8785a..6f82dd6d 100644
--- a/pkg/authority/k8s/client.go
+++ b/pkg/authority/k8s/client.go
@@ -36,10 +36,11 @@ import (
        v1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/types"
-
        "k8s.io/client-go/kubernetes"
        "k8s.io/client-go/rest"
        "k8s.io/client-go/tools/clientcmd"
+       "k8s.io/client-go/tools/leaderelection"
+       "k8s.io/client-go/tools/leaderelection/resourcelock"
        "k8s.io/client-go/util/homedir"
 )
 
@@ -52,6 +53,7 @@ type Client interface {
        UpdateWebhookConfig(options *config.Options, storage cert.Storage)
        GetNamespaceLabels(namespace string) map[string]string
        InitController(paHandler authentication.Handler, apHandler 
authorization.Handler)
+       Resourcelock(storage cert.Storage, options *config.Options) error
 }
 
 type ClientImpl struct {
@@ -366,3 +368,44 @@ func (c *ClientImpl) InitController(
 
        controller.WaitSynced()
 }
+
+func (c *ClientImpl) Resourcelock(storage cert.Storage, options 
*config.Options) error {
+       identity := options.ResourcelockIdentity
+       rlConfig := resourcelock.ResourceLockConfig{
+               Identity: identity,
+       }
+       namespace := options.Namespace
+       _, err := c.kubeClient.CoreV1().Namespaces().Get(context.TODO(), 
namespace, metav1.GetOptions{})
+       if err != nil {
+               namespace = "default"
+       }
+       lock, err := 
resourcelock.New(resourcelock.ConfigMapsLeasesResourceLock, namespace, 
"dubbo-lock-cert", c.kubeClient.CoreV1(), c.kubeClient.CoordinationV1(), 
rlConfig)
+       if err != nil {
+               return err
+       }
+       leaderElectionConfig := leaderelection.LeaderElectionConfig{
+               Lock:          lock,
+               LeaseDuration: 15 * time.Second,
+               RenewDeadline: 10 * time.Second,
+               RetryPeriod:   2 * time.Second,
+               Callbacks: leaderelection.LeaderCallbacks{
+                       // leader
+                       OnStartedLeading: func(ctx context.Context) {
+                               // lock if multi server,refresh signed cert
+                               
storage.SetAuthorityCert(cert.GenerateAuthorityCert(storage.GetRootCert(), 
options.CaValidity))
+                       },
+                       // not leader
+                       OnStoppedLeading: func() {
+                               // TODO should be listen,when cert 
resfresh,should be resfresh
+                       },
+                       // a new leader has been elected
+                       OnNewLeader: func(identity string) {
+                       },
+               },
+       }
+
+       ctx, cancel := context.WithCancel(context.Background())
+       defer cancel()
+       leaderelection.RunOrDie(ctx, leaderElectionConfig)
+       return nil
+}
diff --git a/pkg/authority/security/server.go b/pkg/authority/security/server.go
index f1b5b937..cc5db283 100644
--- a/pkg/authority/security/server.go
+++ b/pkg/authority/security/server.go
@@ -174,8 +174,7 @@ func (s *Server) ScheduleRefreshAuthorityCert() {
                        logger.Sugar().Infof("Authority cert is invalid, 
refresh it.")
                        // TODO lock if multi server
                        // TODO refresh signed cert
-                       
s.CertStorage.SetAuthorityCert(cert2.GenerateAuthorityCert(s.CertStorage.GetRootCert(),
 s.Options.CaValidity))
-
+                       s.KubeClient.Resourcelock(s.CertStorage, s.Options)
                        if s.Options.IsKubernetesConnected {
                                
s.KubeClient.UpdateAuthorityCert(s.CertStorage.GetAuthorityCert().CertPem, 
cert2.EncodePrivateKey(s.CertStorage.GetAuthorityCert().PrivateKey), 
s.Options.Namespace)
                                s.KubeClient.UpdateWebhookConfig(s.Options, 
s.CertStorage)
diff --git a/pkg/authority/security/server_test.go 
b/pkg/authority/security/server_test.go
index ba54eec6..480e401c 100644
--- a/pkg/authority/security/server_test.go
+++ b/pkg/authority/security/server_test.go
@@ -54,6 +54,11 @@ func (s *mockKubeClient) UpdateAuthorityPublicKey(cert 
string) bool {
 func (s *mockKubeClient) UpdateWebhookConfig(options *config.Options, storage 
cert2.Storage) {
 }
 
+func (s *mockKubeClient) Resourcelock(storage cert2.Storage, options 
*config.Options) error {
+       
storage.SetAuthorityCert(cert2.GenerateAuthorityCert(storage.GetRootCert(), 
options.CaValidity))
+       return nil
+}
+
 type mockStorage struct {
        cert2.Storage
        origin cert2.Storage

Reply via email to