Skip to content

Commit 4b12075

Browse files
authored
Merge branch 'master' into dependabot-go_modules-github.com-spf13-cobra-1.1.3
2 parents 3819185 + 71189e8 commit 4b12075

File tree

12 files changed

+363
-10
lines changed

12 files changed

+363
-10
lines changed

.github/workflows/pull-request.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- name: Check out code into the Go module directory
1919
uses: actions/[email protected]
2020
- name: Run GoReleaser
21-
uses: goreleaser/goreleaser-action@v2.4.1
21+
uses: goreleaser/goreleaser-action@v2.5.0
2222
with:
2323
version: latest
2424
args: check

.github/workflows/release.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
with:
1919
go-version: 1.13.x
2020
- name: Run GoReleaser
21-
uses: goreleaser/goreleaser-action@v2.4.1
21+
uses: goreleaser/goreleaser-action@v2.5.0
2222
with:
2323
version: latest
2424
args: release --rm-dist

cmd/config/exec.go renamed to cmd/common/exec.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package config
1+
package common
22

33
import (
44
"io"
@@ -7,7 +7,8 @@ import (
77
"sync"
88
)
99

10-
func execCommand(name string, arg ...string) (err error) {
10+
// ExecCommand exec command
11+
func ExecCommand(name string, arg ...string) (err error) {
1112
command := exec.Command(name, arg...)
1213

1314
//var stdout []byte

cmd/config/config_cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package config
22

33
import "github.com/spf13/cobra"
44

5+
// NewConfigCmd creates config command
56
func NewConfigCmd() (cmd *cobra.Command) {
67
cmd = &cobra.Command{
78
Use: "config",

cmd/config/update.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"github.com/ghodss/yaml"
7+
"github.com/linuxsuren/jcli-ks-plugin/cmd/common"
78
kstypes "github.com/linuxsuren/ks/kubectl-plugin/types"
89
"github.com/spf13/cobra"
910
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -81,6 +82,6 @@ func (o *updateOption) preRunE(_ *cobra.Command, args []string) (err error) {
8182
}
8283

8384
func (o *updateOption) runE(_ *cobra.Command, args []string) (err error) {
84-
err = execCommand("jcli", "config", "update", "--token", o.token, o.name)
85+
err = common.ExecCommand("jcli", "config", "update", "--token", o.token, o.name)
8586
return
8687
}

cmd/pipeline/backup.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package pipeline
2+
3+
import (
4+
"fmt"
5+
"github.com/AlecAivazis/survey/v2"
6+
jCLI "github.com/jenkins-zh/jenkins-cli/client"
7+
"github.com/linuxsuren/jcli-ks-plugin/cmd/common"
8+
"github.com/spf13/cobra"
9+
"os"
10+
"os/exec"
11+
"path"
12+
"strings"
13+
)
14+
15+
func newBackupCommand() (cmd *cobra.Command) {
16+
opt := &backupOption{}
17+
18+
cmd = &cobra.Command{
19+
Use: "backup",
20+
Aliases: []string{"b"},
21+
Short: "Backup KubeSphere Pipeline from Jenkins",
22+
Long: `Backup Ku beSphere Pipeline from Jenkins
23+
It only backups the config of jobs
24+
This command rely on kubectl`,
25+
PreRunE: opt.preRunE,
26+
RunE: opt.runE,
27+
}
28+
29+
flags := cmd.Flags()
30+
flags.StringVarP(&opt.output, "output", "o", "", "The output directory which store the backup files")
31+
flags.StringArrayVarP(&opt.jobs, "jobs", "j", []string{},
32+
"Which jobs do you want to backup")
33+
return
34+
}
35+
36+
type backupOption struct {
37+
jobs []string
38+
output string
39+
}
40+
41+
func (o *backupOption) preRunE(cmd *cobra.Command, args []string) (err error) {
42+
if len(o.jobs) == 0 {
43+
// search jobs from Jenkins, then let users to choose
44+
jclient := &jCLI.JobClient{
45+
JenkinsCore: jCLI.JenkinsCore{
46+
RoundTripper: nil,
47+
},
48+
}
49+
if _, err = getCurrentJenkinsAndClient(&(jclient.JenkinsCore)); err != nil {
50+
return
51+
}
52+
53+
var keyword string
54+
if len(args) > 0 {
55+
keyword = args[0]
56+
}
57+
58+
var items []jCLI.JenkinsItem
59+
var allJobs []string
60+
if items, err = jclient.SearchViaBlue(keyword, 0, 1000); err == nil {
61+
allJobs = make([]string, len(items))
62+
63+
for i, item := range items {
64+
allJobs[i] = item.FullName
65+
}
66+
}
67+
68+
prompt := &survey.MultiSelect{
69+
Message: "Please select the pipelines that you want to backup:",
70+
Options: allJobs,
71+
}
72+
if err = survey.AskOne(prompt, &o.jobs); err == nil {
73+
for i, item := range o.jobs {
74+
o.jobs[i] = strings.Join(strings.Split("/"+item, "/"), "/job/")
75+
}
76+
}
77+
}
78+
79+
if o.output == "" {
80+
o.output = path.Dir(".")
81+
}
82+
return
83+
}
84+
85+
func (o *backupOption) runE(_ *cobra.Command, _ []string) (err error) {
86+
var podName string
87+
if podName, err = getJenkinsPodName(); err != nil {
88+
err = fmt.Errorf("cannot get ks-jenkins pod, %v", err)
89+
return
90+
}
91+
92+
for _, job := range o.jobs {
93+
job = strings.TrimPrefix(job, "/")
94+
job = strings.TrimSuffix(job, "/")
95+
job = strings.ReplaceAll(job, "job/", "jobs/")
96+
97+
if err = os.MkdirAll(path.Dir(podName), 0666); err != nil {
98+
err = fmt.Errorf("cannot mkdir %s, %v", podName, err)
99+
return
100+
}
101+
102+
cmd := fmt.Sprintf("kubectl cp -n kubesphere-devops-system %s:var/jenkins_home/%s/config.xml %s/config.xml", podName, job, job)
103+
fmt.Println("start to backup", fmt.Sprintf("/var/jenkins_home/%s/config.xml", job))
104+
err = common.ExecCommand("kubectl", strings.Split(cmd, " ")[1:]...)
105+
if err != nil {
106+
return
107+
}
108+
}
109+
return
110+
}
111+
112+
func getJenkinsPodName() (name string, err error) {
113+
var data []byte
114+
cmd := exec.Command("kubectl", strings.Split("-n kubesphere-devops-system get pod -l app=ks-jenkins -o custom-columns=NAME:.metadata.name --no-headers=true", " ")...)
115+
if data, err = cmd.Output(); err == nil {
116+
name = strings.TrimSpace(string(data))
117+
}
118+
return
119+
}

cmd/pipeline/inner.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package pipeline
2+
3+
import (
4+
"fmt"
5+
"github.com/jenkins-zh/jenkins-cli/app/cmd/keyring"
6+
"github.com/jenkins-zh/jenkins-cli/client"
7+
"github.com/mitchellh/go-homedir"
8+
"gopkg.in/yaml.v2"
9+
"io/ioutil"
10+
"os"
11+
12+
appCfg "github.com/jenkins-zh/jenkins-cli/app/config"
13+
)
14+
15+
/**
16+
* These code lines should be moved into github.com/jenkins-zh/jenkins-cli at sometime
17+
*/
18+
19+
var config *appCfg.Config
20+
21+
func getCurrentJenkins() (cfg *appCfg.JenkinsServer, err error) {
22+
if err = loadDefaultConfig(); err == nil {
23+
cfg = findJenkinsByName(config.Current)
24+
}
25+
return
26+
}
27+
28+
func getClient(jenkins *appCfg.JenkinsServer, jClient *client.JenkinsCore) {
29+
jClient.URL = jenkins.URL
30+
jClient.UserName = jenkins.UserName
31+
jClient.Token = jenkins.Token
32+
jClient.Proxy = jenkins.Proxy
33+
jClient.ProxyAuth = jenkins.ProxyAuth
34+
jClient.InsecureSkipVerify = jenkins.InsecureSkipVerify
35+
}
36+
37+
func getCurrentJenkinsAndClient(jClient *client.JenkinsCore) (jenkins *appCfg.JenkinsServer, err error) {
38+
if jenkins, err = getCurrentJenkins(); err == nil && jenkins != nil {
39+
getClient(jenkins, jClient)
40+
}
41+
return
42+
}
43+
44+
func findJenkinsByName(name string) (jenkinsServer *appCfg.JenkinsServer) {
45+
if config == nil {
46+
return
47+
}
48+
49+
for _, cfg := range config.JenkinsServers {
50+
if cfg.Name == name {
51+
jenkinsServer = &cfg
52+
break
53+
}
54+
}
55+
return
56+
}
57+
58+
func getDefaultConfigPath() (configPath string, err error) {
59+
var userHome string
60+
userHome, err = homedir.Dir()
61+
if err == nil {
62+
configPath = fmt.Sprintf("%s/.jenkins-cli.yaml", userHome)
63+
}
64+
return
65+
}
66+
67+
func loadDefaultConfig() (err error) {
68+
var configPath string
69+
if configPath, err = getDefaultConfigPath(); err == nil {
70+
if _, err = os.Stat(configPath); err == nil {
71+
err = loadConfig(configPath)
72+
}
73+
}
74+
return
75+
}
76+
77+
func loadConfig(path string) (err error) {
78+
var content []byte
79+
if content, err = ioutil.ReadFile(path); err == nil {
80+
err = yaml.Unmarshal([]byte(content), &config)
81+
82+
keyring.LoadTokenFromKeyring(config)
83+
}
84+
return
85+
}

cmd/pipeline/pipeline_root.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package pipeline
2+
3+
import "github.com/spf13/cobra"
4+
5+
// NewPipelineRootCommand returns the root command of pipeline
6+
func NewPipelineRootCommand() (cmd *cobra.Command) {
7+
cmd = &cobra.Command{
8+
Use: "pipeline",
9+
Aliases: []string{"pip"},
10+
}
11+
12+
cmd.AddCommand(newBackupCommand(), newRestoreCommand())
13+
return
14+
}

cmd/pipeline/restore.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package pipeline
2+
3+
import (
4+
"fmt"
5+
"github.com/linuxsuren/jcli-ks-plugin/cmd/common"
6+
"github.com/spf13/cobra"
7+
"os"
8+
"path"
9+
"path/filepath"
10+
"strings"
11+
)
12+
13+
func newRestoreCommand() (cmd *cobra.Command) {
14+
opt := &restoreOption{}
15+
16+
cmd = &cobra.Command{
17+
Use: "restore",
18+
Short: "Restore KubeSphere Pipeline to Jenkins",
19+
Long: `Restore KubeSphere Pipeline to Jenkins
20+
It only restore the config of jobs
21+
This command rely on kubectl`,
22+
PreRunE: opt.preRunE,
23+
RunE: opt.runE,
24+
}
25+
26+
flags := cmd.Flags()
27+
flags.StringVarP(&opt.input, "input", "i", "", "The input directory which store the backup files")
28+
return
29+
}
30+
31+
type restoreOption struct {
32+
input string
33+
}
34+
35+
func (o *restoreOption) preRunE(cmd *cobra.Command, args []string) (err error) {
36+
if o.input == "" {
37+
o.input = path.Dir(".")
38+
}
39+
return
40+
}
41+
42+
func (o *restoreOption) runE(cmd *cobra.Command, args []string) (err error) {
43+
var podName string
44+
if podName, err = getJenkinsPodName(); err != nil {
45+
err = fmt.Errorf("cannot get ks-jenkins pod, %v", err)
46+
return
47+
}
48+
49+
err = filepath.Walk(fmt.Sprintf("%s/jobs", o.input), func(path string, info os.FileInfo, err error) error {
50+
if strings.HasSuffix(path, "config.xml") {
51+
cmd := fmt.Sprintf("kubectl cp -n kubesphere-devops-system %s %s:var/jenkins_home/%s", path, podName, path)
52+
fmt.Println("start to restore", path)
53+
err = common.ExecCommand("kubectl", strings.Split(cmd, " ")[1:]...)
54+
if err != nil {
55+
return err
56+
}
57+
}
58+
return nil
59+
})
60+
return
61+
}

cmd/root.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cmd
22

33
import (
44
"github.com/linuxsuren/jcli-ks-plugin/cmd/config"
5+
"github.com/linuxsuren/jcli-ks-plugin/cmd/pipeline"
56
"github.com/spf13/cobra"
67
)
78

@@ -12,6 +13,6 @@ func NewKSPlugin() (cmd *cobra.Command) {
1213
Short: "jcli plugin for KubeSphere",
1314
}
1415

15-
cmd.AddCommand(config.NewConfigCmd())
16+
cmd.AddCommand(config.NewConfigCmd(), pipeline.NewPipelineRootCommand())
1617
return
1718
}

0 commit comments

Comments
 (0)