From 7ee06eed340aedf0dcf3e907f96ca64cbf17be67 Mon Sep 17 00:00:00 2001 From: KubeSphere CI Bot <47586280+ks-ci-bot@users.noreply.github.com> Date: Thu, 13 Apr 2023 17:38:42 +0800 Subject: [PATCH] only support update password by jwt (#939) Co-authored-by: jackyu --- cmd/tools/app/init_config.go | 107 ++++++++++++++++++----------------- cmd/tools/app/root.go | 11 +++- cmd/tools/jwt/app/agent.go | 24 +++----- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/cmd/tools/app/init_config.go b/cmd/tools/app/init_config.go index 232c9fd3..7267076d 100644 --- a/cmd/tools/app/init_config.go +++ b/cmd/tools/app/init_config.go @@ -26,51 +26,36 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/klog/v2" jwt "kubesphere.io/devops/cmd/tools/jwt/app" - "kubesphere.io/devops/pkg/client/k8s" + "kubesphere.io/devops/pkg/client/devops/jenkins" "kubesphere.io/devops/pkg/config" ) type initConfigOption struct { *ToolOption - ksNamespace string - ksConfigMapName string + ksNamespace string + ksConfigmap string } -func (o *initConfigOption) preRunE(cmd *cobra.Command, args []string) (err error) { - o.K8sClient, err = k8s.NewKubernetesClient(k8s.NewKubernetesOptions()) - return +func (o *initConfigOption) preRunE(cmd *cobra.Command, args []string) error { + return o.initK8sClient() } -func (o *initConfigOption) runE(cmd *cobra.Command, args []string) (err error) { - // if kubesphere-config in namespace kubesphere-system not exist, generate devops.password by jwt - // used for deploy devops independence - if _, _, err = o.getKubesphereConfig(o.ksNamespace, o.ksConfigMapName); err != nil { - if !errors.IsNotFound(err) { - klog.Error("check if kubesphere-config exist failed") - return - } - klog.Infof("update configmap %s in %s by jwt", o.ConfigMapName, o.Namespace) - err = jwt.JwtFunc("", o.Namespace, o.ConfigMapName) - return - } - - klog.Infof("get patch configuration from configmap %s in %s", o.ksConfigMapName, o.ksNamespace) - var updateConfig map[string]interface{} - if updateConfig, err = o.getPatchConfigFromKs(); err != nil { - return +func (o *initConfigOption) runE(cmd *cobra.Command, args []string) error { + patchConf, err := o.getPatchConfig() + if err != nil { + return err } - if len(updateConfig) == 0 { - klog.Info("nothing need to update in configmap, ignore") - return + if len(patchConf) == 0 { + klog.Info("the devops-config doesn't need to update, ignore") + return nil } - klog.Infof("update configmap %s in %s ..", o.ConfigMapName, o.Namespace) - err = o.updateKubeSphereConfig(updateConfig) - return + klog.Infof("update configmap %s in %s ..", o.Configmap, o.Namespace) + return o.updateConfig(patchConf) } -func (o initConfigOption) getKubesphereConfig(namespace, configmapName string) (cm *v1.ConfigMap, ksYaml map[string]interface{}, err error) { +func (o initConfigOption) getKubesphereYaml(namespace, configmapName string) (cm *v1.ConfigMap, ksYaml map[string]interface{}, err error) { if cm, err = o.K8sClient.Kubernetes().CoreV1().ConfigMaps(namespace). Get(context.TODO(), configmapName, metav1.GetOptions{}); err != nil { return @@ -81,37 +66,55 @@ func (o initConfigOption) getKubesphereConfig(namespace, configmapName string) ( return } -func (o *initConfigOption) getPatchConfigFromKs() (conf map[string]interface{}, err error) { - var ksConf, devopsConf map[string]interface{} - if _, ksConf, err = o.getKubesphereConfig(o.ksNamespace, o.ksConfigMapName); err != nil { +func (o *initConfigOption) getPatchConfig() (patchConf map[string]interface{}, err error) { + patchConf = map[string]interface{}{} + + var devopsConf map[string]interface{} + if _, devopsConf, err = o.getKubesphereYaml(o.Namespace, o.Configmap); err != nil { return } - if _, devopsConf, err = o.getKubesphereConfig(o.Namespace, o.ConfigMapName); err != nil { - return + jwtSecret := devopsConf["authentication"].(map[string]interface{})["jwtSecret"].(string) + if jwtSecret == "" { + klog.Info("generate jwt secret ..") + jwtSecret = jwt.GenerateJwtSecret() + patchConf["authentication"] = map[string]interface{}{"jwtSecret": jwtSecret} + } + password := devopsConf["devops"].(map[string]interface{})["password"].(string) + if password == jenkins.DefaultAdminPassword || password == "" { + klog.Info("generate devops password by jwt ..") + password = jwt.GeneratePassword(jwtSecret) + patchConf["devops"] = map[string]interface{}{"password": password} } - conf = map[string]interface{}{} - - password := ksConf["devops"].(map[string]interface{})["password"].(string) - devopsPassword := devopsConf["devops"].(map[string]interface{})["password"].(string) - if password == "" { - err = fmt.Errorf("the password in configmap %s is nil", o.ksConfigMapName) + // copy sonarqube from kubesphere-config if exist + var ksConf map[string]interface{} + if _, ksConf, err = o.getKubesphereYaml(o.ksNamespace, o.ksConfigmap); err != nil { + if errors.IsNotFound(err) { + err = nil + } return } - if devopsPassword != password { - conf["devops"] = map[string]interface{}{"password": password} - } + if sonarqubeObj, exist := ksConf["sonarQube"]; exist { + // if sonarqube in devops-config is same as that in kubesphere-config, ignore + var devopsSonarqubeObj interface{} + if devopsSonarqubeObj, exist = devopsConf["sonarQube"]; exist { + sonarqube := sonarqubeObj.(map[string]interface{}) + devopsSonarqube := devopsSonarqubeObj.(map[string]interface{}) + if devopsSonarqube["host"] == sonarqube["host"] && devopsSonarqube["token"] == sonarqube["token"] { + return + } + } - if sonarqube, exist := ksConf["sonarQube"]; exist { - conf["sonarQube"] = sonarqube + patchConf["sonarQube"] = sonarqubeObj } + return } -func (o *initConfigOption) updateKubeSphereConfig(updateConfig map[string]interface{}) error { - devopsCm, devopsKsConf, err := o.getKubesphereConfig(o.Namespace, o.ConfigMapName) +func (o *initConfigOption) updateConfig(updateConfig map[string]interface{}) error { + devopsCm, devopsKsConf, err := o.getKubesphereYaml(o.Namespace, o.Configmap) if err != nil { - return fmt.Errorf("cannot found ConfigMap %s/%s, %v", o.Namespace, o.ConfigMapName, err) + return fmt.Errorf("cannot found ConfigMap %s/%s, %v", o.Namespace, o.Configmap, err) } patchedKubeSphereConfig, err := patchKubeSphereConfig(devopsKsConf, updateConfig) @@ -143,9 +146,9 @@ func NewInitCmd() (cmd *cobra.Command) { flags := initCmd.Flags() flags.StringVar(&opt.ksNamespace, "ks-namespace", "kubesphere-system", - "The namespace of kubesphere namespace") - flags.StringVar(&opt.ksConfigMapName, "ks-configmap", "kubesphere-config", - "The name of kubesphere configmap") + "The namespace of kubesphere core service") + flags.StringVar(&opt.ksConfigmap, "ks-configmap", "kubesphere-config", + "The configmap name of kubesphere core service configuration") return initCmd } diff --git a/cmd/tools/app/root.go b/cmd/tools/app/root.go index f9986ba7..cd83f38a 100644 --- a/cmd/tools/app/root.go +++ b/cmd/tools/app/root.go @@ -24,12 +24,17 @@ import ( var toolOpt *ToolOption type ToolOption struct { - Namespace string - ConfigMapName string + Namespace string + Configmap string K8sClient k8s.Client } +func (o *ToolOption) initK8sClient() (err error) { + o.K8sClient, err = k8s.NewKubernetesClient(k8s.NewKubernetesOptions()) + return +} + func (o *ToolOption) runHelpE(cmd *cobra.Command, args []string) error { return cmd.Help() } @@ -47,7 +52,7 @@ func NewToolsCmd() (cmd *cobra.Command) { flags := rootCmd.PersistentFlags() flags.StringVarP(&toolOpt.Namespace, "namespace", "n", "kubesphere-devops-system", "The namespace of DevOps service") - flags.StringVarP(&toolOpt.ConfigMapName, "configmap", "c", "devops-config", + flags.StringVarP(&toolOpt.Configmap, "configmap", "c", "devops-config", "The configmap name of DevOps service") rootCmd.AddCommand(NewInitCmd()) diff --git a/cmd/tools/jwt/app/agent.go b/cmd/tools/jwt/app/agent.go index 04e8a158..66174a76 100644 --- a/cmd/tools/jwt/app/agent.go +++ b/cmd/tools/jwt/app/agent.go @@ -16,21 +16,13 @@ limitations under the License. package app -// JwtFunc a agent func to generate and update devops.password that called by others in different package -func JwtFunc(secret, namespace, configmap string) (err error) { - opt := &jwtOption{ - secret: secret, - output: "configmap", - overrideJenkinsToken: true, - namespace: namespace, - name: configmap, - k8sClientFactory: &DefaultK8sClientFactory{}, - } - - if err = opt.preRunE(nil, []string{}); err != nil { - return - } +// GenerateJwtSecret a agent func to generate jwt secret that called by others in different package +func GenerateJwtSecret() string { + opt := &jwtOption{} + return opt.generateSecret() +} - err = opt.runE(nil, []string{}) - return +// GeneratePassword a agent func to generate devops password that called by others in different package +func GeneratePassword(secret string) string { + return generateJWT(secret) }