未验证 提交 99bdef3b 编写于 作者: Y Yanjun Shi 提交者: GitHub

Add support upgrade all plugins (#258)

* Add all and compatible for upgrade plugins

* Add comment

* Add some unit test

* update unit test

* updated unified call http request

* Update unit test coverage

* Update unit test coverage

* Temporarily comment out the compatibility section

* comment the other test unit

* restore some comment

* delete files that do not exist

* delete comment content for completion method

* Update pluginApi_test_common.go
Co-authored-by: LinuxSuRen's avatarZhao Xiaojie <rick@jenkins-zh.cn>
上级 9a626861
......@@ -17,6 +17,7 @@ import (
// PluginUpgradeOption option for plugin list command
type PluginUpgradeOption struct {
Filter []string
All bool
RoundTripper http.RoundTripper
}
......@@ -25,7 +26,9 @@ var pluginUpgradeOption PluginUpgradeOption
func init() {
pluginCmd.AddCommand(pluginUpgradeCmd)
pluginUpgradeCmd.Flags().StringArrayVarP(&pluginUpgradeOption.Filter, "filter", "", []string{}, "Filter for the list, like: name=foo")
pluginUpgradeCmd.Flags().StringArrayVarP(&pluginUpgradeOption.Filter, "filter", "", []string{}, i18n.T("Filter for the list, like: name=foo"))
pluginUpgradeCmd.Flags().BoolVarP(&pluginUpgradeOption.All, "all", "", false, i18n.T("Upgrade all plugins for updated"))
}
var pluginUpgradeCmd = &cobra.Command{
......@@ -43,7 +46,11 @@ var pluginUpgradeCmd = &cobra.Command{
var err error
targetPlugins := make([]string, 0)
if len(args) == 0 {
if pluginUpgradeOption.All {
if upgradeablePlugins, err := pluginUpgradeOption.findUpgradeablePlugins(jclient); err == nil {
targetPlugins = pluginUpgradeOption.convertToArray(upgradeablePlugins)
}
} else if len(args) == 0 {
var upgradeablePlugins []client.InstalledPlugin
if upgradeablePlugins, err = pluginUpgradeOption.findUpgradeablePlugins(jclient); err == nil {
prompt := &survey.MultiSelect{
......@@ -56,7 +63,7 @@ var pluginUpgradeCmd = &cobra.Command{
targetPlugins = args
}
if err == nil {
if err == nil && len(targetPlugins) != 0 {
err = jclient.InstallPlugin(targetPlugins)
}
helper.CheckErr(cmd, err)
......@@ -90,7 +97,6 @@ func (p *PluginUpgradeOption) findUpgradeablePlugins(jclient *client.PluginManag
if plugins, err = jclient.GetPlugins(1); err != nil {
return
}
for _, plugin := range plugins.Plugins {
if !plugin.HasUpdate {
continue
......@@ -104,3 +110,48 @@ func (p *PluginUpgradeOption) findUpgradeablePlugins(jclient *client.PluginManag
}
return
}
/*func (p *PluginUpgradeOption) findCompatiblePlugins(installedPlugins []client.InstalledPlugin) (plugins []string) {
plugins = make([]string, 0)
var pluginNames string
for i, plugin := range installedPlugins {
if !strings.Contains(pluginNames, plugin.ShortName) {
if len(installedPlugins) > i+1 {
pluginNames += plugin.ShortName + "|"
} else {
pluginNames += plugin.ShortName
}
}
}
plugins = pluginUpgradeOption.assembleData(installedPlugins, pluginNames)
return
}
func (p *PluginUpgradeOption) assembleData(installedPlugins []client.InstalledPlugin, pluginNames string) (plugins []string) {
pluginAPI := client.PluginAPI{}
if pluginsList, err := pluginAPI.BatchSearchPlugins(pluginNames); err == nil {
for _, pluginInfo := range pluginsList {
for _, plugin := range installedPlugins {
if plugin.ShortName == pluginInfo.Name {
var hasSecurity bool
securityWarnings := pluginInfo.SecurityWarnings
hasSecurity = p.checkSecurity(securityWarnings)
if !hasSecurity {
plugins = append(plugins, pluginInfo.Name)
}
}
}
}
}
return
}
func (p *PluginUpgradeOption) checkSecurity(securityWarnings []client.SecurityWarning) (hasSecurity bool) {
for _, securityWarning := range securityWarnings {
if securityWarning.Active {
hasSecurity = true
break
}
}
return
}*/
......@@ -84,5 +84,26 @@ var _ = Describe("plugin upgrade command", func() {
Expect(len(plugins)).To(Equal(1))
Expect(plugins[0]).To(Equal(pluginName))
})
It("upgrade all plugin, should success", func() {
data, err := generateSampleConfig()
Expect(err).To(BeNil())
err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664)
Expect(err).To(BeNil())
request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins")
request.SetBasicAuth("admin", "111e3a2f0231198855dceaff96f20540a9")
//client.PrepareShowPlugins(roundTripper, pluginName)
client.PrepareForInstallPlugin(roundTripper, "http://localhost:8080/jenkins", pluginName, "admin", "111e3a2f0231198855dceaff96f20540a9")
rootCmd.SetArgs([]string{"plugin", "upgrade", "--all"})
buf := new(bytes.Buffer)
rootCmd.SetOutput(buf)
_, err = rootCmd.ExecuteC()
Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(""))
})
})
})
......@@ -51,8 +51,8 @@ type PluginInfo struct {
Title string `json:"title"`
URL string `json:"url"`
Version string `json:"version"`
Stats PluginInfoStats
SecurityWarnings []SecurityWarning `json:"securityWarnings"`
Stats PluginInfoStats
}
// PluginInfoStats is the plugin info stats
......@@ -73,10 +73,34 @@ type PluginInstallationInfo struct {
Percentage float64
}
// SecurityWarning represents the plugin security-warining info
type SecurityWarning struct {
Active bool
ID string
Message string
URL string
Versions []Version
}
// Version represents the SecurityWarning cover version
type Version struct {
firstVersion string
lastVersion string
}
// Plugins represents multi PluginInfo
type Plugins struct {
Limit int `json:"limit"`
Page int `json:"page"`
Pages int `json:"pages"`
Total int `json:"total"`
Plugins []PluginInfo `json:"plugins"`
}
// ShowTrend show the trend of plugins
func (d *PluginAPI) ShowTrend(name string) (trend string, err error) {
var plugin *PluginInfo
if plugin, err = d.getPlugin(name); err != nil {
if plugin, err = d.GetPlugin(name); err != nil {
return
}
......@@ -141,7 +165,8 @@ func (d *PluginAPI) download(url string, name string) (err error) {
return
}
func (d *PluginAPI) getPlugin(name string) (plugin *PluginInfo, err error) {
// GetPlugin will get the plugin information
func (d *PluginAPI) GetPlugin(name string) (plugin *PluginInfo, err error) {
var cli = http.Client{}
if d.RoundTripper == nil {
cli.Transport = &http.Transport{
......@@ -168,7 +193,7 @@ func (d *PluginAPI) getPlugin(name string) (plugin *PluginInfo, err error) {
}
func (d *PluginAPI) collectDependencies(pluginName string) (plugins []PluginInfo) {
plugin, err := d.getPlugin(pluginName)
plugin, err := d.GetPlugin(pluginName)
if err != nil {
log.Println("can't get the plugin by name:", pluginName)
panic(err)
......@@ -192,3 +217,31 @@ func (d *PluginAPI) collectDependencies(pluginName string) (plugins []PluginInfo
}
return
}
// BatchSearchPlugins will batch search plugins
func (d *PluginAPI) BatchSearchPlugins(pluginNames string) (plugins []PluginInfo, err error) {
var cli = http.Client{}
if d.RoundTripper == nil {
cli.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
} else {
cli.Transport = d.RoundTripper
}
pluginAPI := fmt.Sprintf("https://plugins.jenkins.io/api/plugins/?q=%s&page=1&limit=1000", pluginNames)
logger.Debug("fetch data from plugin API", zap.String("url", pluginAPI))
var resp *http.Response
if resp, err = cli.Get(pluginAPI); err == nil {
var body []byte
if body, err = ioutil.ReadAll(resp.Body); err == nil {
var pluginsInfo Plugins
err = json.Unmarshal(body, &pluginsInfo)
plugins = pluginsInfo.Plugins
}
}
return
}
......@@ -133,5 +133,14 @@ var _ = Describe("plugin api test", func() {
defer os.Remove("fake.hpi")
})
It("batch search plugins", func() {
names = []string{"fake"}
PrepareShowPlugins(roundTripper, "fake")
plugins, _ := pluginAPI.BatchSearchPlugins("fake")
Expect(len(plugins)).To(Equal(0))
})
})
})
......@@ -15,7 +15,6 @@ func PrepareShowTrend(roundTripper *mhttp.MockRoundTripper, keyword string) (
request, _ := http.NewRequest("GET", fmt.Sprintf("https://plugins.jenkins.io/api/plugin/%s", keyword), nil)
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`
{"name":"fake","version": "0.1.8","url": "http://updates.jenkins-ci.org/download/plugins/hugo/0.1.8/hugo.hpi",
......@@ -75,3 +74,23 @@ func PrepareCheckUpdate(roundTripper *mhttp.MockRoundTripper, rootURL, user, pas
request, _ := http.NewRequest("POST", api, nil)
PrepareCommonPost(request, "", roundTripper, user, password, rootURL)
}
// PrepareShowPlugins only for test
func PrepareShowPlugins(roundTripper *mhttp.MockRoundTripper, keyword string) (
response *http.Response) {
request, _ := http.NewRequest("GET", fmt.Sprintf("https://plugins.jenkins.io/api/plugins/?q=%s&page=1&limit=1000", keyword), nil)
response = &http.Response{
StatusCode: 200,
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`
"limit":1000,"page":1,"pages"":1,"total":1,
"plugins":[{"name":"fake","version": "0.1.8","url": "http://updates.jenkins-ci.org/download/plugins/hugo/0.1.8/hugo.hpi",
"stats": {"installations":[{"total":1512},{"total":3472},{"total":4385},{"total":3981}]},
"securityWarnings":[{"versions":[{"firstVersion":null,"lastVersion":"0.1.8"}],"id":"SECURITY-659",
"message":"XML External Entity (XXE) processing vulnerability","url":"https://jenkins.io/security/advisory/2018-02-05/","active":true}]}]
`)),
}
roundTripper.EXPECT().
RoundTrip(request).Return(response, nil)
return
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册