Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MM-19445 - Added version information to plugin diagnostics data #13408

Merged
merged 31 commits into from Jan 16, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b608523
MM-19609 - Add new prepackage configuration settings (#13062)
alifarooq0 Nov 14, 2019
128e447
Add signatures to the prepackaged plugins (#13138)
iomodo Nov 18, 2019
c480860
Merge remote-tracking branch 'origin/master' into rework_prepackaged_…
alifarooq0 Nov 28, 2019
49e3394
Merge remote-tracking branch 'origin/master' into rework_prepackaged_…
lieut-data Dec 6, 2019
f5fff09
Merge remote-tracking branch 'origin/master' into mm-19606-feature-re…
marianunez Dec 10, 2019
5a33707
MM-19612 - Support querying local plugin marketplace when upst… (#13250)
alifarooq0 Dec 11, 2019
55d739d
MM-19614- Updated Marketplace Service error id (#13388)
marianunez Dec 16, 2019
ff82954
Added version information to plugin diagnostics data
marianunez Dec 17, 2019
474c932
Merge remote-tracking branch 'origin/master' into mm-19606-feature-re…
marianunez Dec 17, 2019
5aa5aa3
Merge remote-tracking branch 'origin/master' into mm-19606-feature-re…
lieut-data Dec 17, 2019
0d2e3c5
[MM-19610] Consume prepackaged plugins (#13005)
iomodo Dec 17, 2019
1264fbe
MM-19613 - Include prepackaged plugins in marketplace results (#13433)
marianunez Dec 20, 2019
2c3e08f
MM-21263 - Use EnableRemoteMarketplace in marketplace install… (#13438)
alifarooq0 Dec 20, 2019
7b42f56
Merge remote-tracking branch 'origin/master' into mm-19606-feature-re…
marianunez Jan 8, 2020
b84b23f
Initial PR feedback
marianunez Jan 8, 2020
25a1572
Ordered imports properly
marianunez Jan 8, 2020
855c0bd
Updated DownloadURL to return slice of bytes
marianunez Jan 8, 2020
d2c9693
Fixed method typo
marianunez Jan 8, 2020
ce281cc
Fixed logging
marianunez Jan 8, 2020
ce5be15
Added read lock for prepackaged plugins list
marianunez Jan 9, 2020
0bbf911
Merge remote-tracking branch 'origin/master' into mm-19606-feature-re…
marianunez Jan 9, 2020
ebf5eec
PR Feedback
marianunez Jan 9, 2020
d991135
Added condition to only install prepackaged plugin if it was previous…
marianunez Jan 10, 2020
bbcb169
Linting
marianunez Jan 10, 2020
c353fdf
Updated to check plugin state in config
marianunez Jan 10, 2020
29d7b85
Merge remote-tracking branch 'origin/mm-19606-feature-rework-prepacka…
marianunez Jan 10, 2020
6e2847f
Flatten out version number to its own entries. Added webex
marianunez Jan 10, 2020
9486db3
Updated tests
marianunez Jan 10, 2020
8673fcd
Merge remote-tracking branch 'origin/master' into mm-19606-feature-re…
marianunez Jan 10, 2020
6068754
Merge remote-tracking branch 'origin/mm-19606-feature-rework-prepacka…
marianunez Jan 10, 2020
a989334
Merge remote-tracking branch 'origin/master' into MM-19445
marianunez Jan 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions api4/plugin.go
Expand Up @@ -347,12 +347,14 @@ func parseMarketplacePluginFilter(u *url.URL) (*model.MarketplacePluginFilter, e

filter := u.Query().Get("filter")
serverVersion := u.Query().Get("server_version")
localOnly := u.Query().Get("local_only") == "true"

return &model.MarketplacePluginFilter{
Page: page,
PerPage: perPage,
Filter: filter,
ServerVersion: serverVersion,
LocalOnly: localOnly,
}, nil
}

Expand Down
163 changes: 162 additions & 1 deletion api4/plugin_test.go
Expand Up @@ -61,6 +61,10 @@ func TestPlugin(t *testing.T) {
CheckNoError(t, resp)
assert.Equal(t, "testplugin", manifest.Id)

ok, resp := th.SystemAdminClient.RemovePlugin(manifest.Id)
CheckNoError(t, resp)
require.True(t, ok)

t.Run("install plugin from URL with slow response time", func(t *testing.T) {
if testing.Short() {
t.Skip("skipping test to install plugin from a slow response server")
Expand Down Expand Up @@ -163,7 +167,7 @@ func TestPlugin(t *testing.T) {
assert.False(t, found)

// Successful activate
ok, resp := th.SystemAdminClient.EnablePlugin(manifest.Id)
ok, resp = th.SystemAdminClient.EnablePlugin(manifest.Id)
CheckNoError(t, resp)
assert.True(t, ok)

Expand Down Expand Up @@ -767,6 +771,163 @@ func TestSearchGetMarketplacePlugins(t *testing.T) {
plugins, resp = th.SystemAdminClient.GetMarketplacePlugins(&model.MarketplacePluginFilter{Filter: "NOFILTER"})
CheckNoError(t, resp)
require.Nil(t, plugins)

// cleanup
ok, resp := th.SystemAdminClient.RemovePlugin(newPluginV1.Manifest.Id)
CheckNoError(t, resp)
assert.True(t, ok)

ok, resp = th.SystemAdminClient.RemovePlugin(newPluginV2.Manifest.Id)
CheckNoError(t, resp)
assert.True(t, ok)
})
}

func TestGetLocalPluginInMarketplace(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()

samplePlugins := []*model.MarketplacePlugin{
{
BaseMarketplacePlugin: &model.BaseMarketplacePlugin{
HomepageURL: "https://example.com/mattermost/mattermost-plugin-nps",
IconData: "https://example.com/icon.svg",
DownloadURL: "www.github.com/example",
Manifest: &model.Manifest{
Id: "testplugin_v2",
Name: "testplugin_v2",
Description: "dsgsdg_v2",
Version: "1.2.2",
MinServerVersion: "",
},
},
InstalledVersion: "",
},
}

testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK)
json, err := json.Marshal([]*model.MarketplacePlugin{samplePlugins[0]})
require.NoError(t, err)
res.Write(json)
}))
defer testServer.Close()

th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.Enable = true
*cfg.PluginSettings.EnableMarketplace = true
*cfg.PluginSettings.MarketplaceUrl = testServer.URL
})

t.Run("Get plugins with EnableRemoteMarketplace enabled", func(t *testing.T) {

th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.EnableRemoteMarketplace = true
})

plugins, resp := th.SystemAdminClient.GetMarketplacePlugins(&model.MarketplacePluginFilter{})
CheckNoError(t, resp)

require.Len(t, plugins, len(samplePlugins))
require.Equal(t, samplePlugins, plugins)
})

t.Run("get remote and local plugins", func(t *testing.T) {

th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.EnableRemoteMarketplace = true
*cfg.PluginSettings.EnableUploads = true
})

// Upload one local plugin
path, _ := fileutils.FindDir("tests")
tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz"))
require.NoError(t, err)

manifest, resp := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
CheckNoError(t, resp)

plugins, resp := th.SystemAdminClient.GetMarketplacePlugins(&model.MarketplacePluginFilter{})
CheckNoError(t, resp)

require.Len(t, plugins, 2)

ok, resp := th.SystemAdminClient.RemovePlugin(manifest.Id)
CheckNoError(t, resp)
assert.True(t, ok)
})

t.Run("EnableRemoteMarketplace disabled", func(t *testing.T) {

th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.EnableRemoteMarketplace = false
*cfg.PluginSettings.EnableUploads = true
})

// No marketplace plugins returned
plugins, resp := th.SystemAdminClient.GetMarketplacePlugins(&model.MarketplacePluginFilter{})
CheckNoError(t, resp)

require.Len(t, plugins, 0)

// Upload one local plugin
path, _ := fileutils.FindDir("tests")
tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz"))
require.NoError(t, err)

manifest, resp := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
CheckNoError(t, resp)

newPlugin := &model.MarketplacePlugin{
BaseMarketplacePlugin: &model.BaseMarketplacePlugin{
Manifest: manifest,
},
InstalledVersion: manifest.Version,
}

plugins, resp = th.SystemAdminClient.GetMarketplacePlugins(&model.MarketplacePluginFilter{})
CheckNoError(t, resp)

// Only get the local plugins
require.Len(t, plugins, 1)
require.Equal(t, newPlugin, plugins[0])

ok, resp := th.SystemAdminClient.RemovePlugin(manifest.Id)
CheckNoError(t, resp)
assert.True(t, ok)
})

t.Run("local_only true", func(t *testing.T) {

th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PluginSettings.EnableRemoteMarketplace = true
*cfg.PluginSettings.EnableUploads = true
})

// Upload one local plugin
path, _ := fileutils.FindDir("tests")
tarData, err := ioutil.ReadFile(filepath.Join(path, "testplugin.tar.gz"))
require.NoError(t, err)

manifest, resp := th.SystemAdminClient.UploadPlugin(bytes.NewReader(tarData))
CheckNoError(t, resp)

newPlugin := &model.MarketplacePlugin{
BaseMarketplacePlugin: &model.BaseMarketplacePlugin{
Manifest: manifest,
},
InstalledVersion: manifest.Version,
}

plugins, resp := th.SystemAdminClient.GetMarketplacePlugins(&model.MarketplacePluginFilter{LocalOnly: true})
CheckNoError(t, resp)

require.Len(t, plugins, 1)
require.Equal(t, newPlugin, plugins[0])

ok, resp := th.SystemAdminClient.RemovePlugin(manifest.Id)
CheckNoError(t, resp)
assert.True(t, ok)
})
}

Expand Down
57 changes: 35 additions & 22 deletions app/diagnostics.go
Expand Up @@ -100,12 +100,16 @@ func pluginSetting(pluginSettings *model.PluginSettings, plugin, key string, def
return defaultValue
}

func pluginActivated(pluginStates map[string]*model.PluginState, pluginId string) bool {
state, ok := pluginStates[pluginId]
func pluginData(availablePluginsData map[string]interface{}, pluginId string) interface{} {
data, ok := availablePluginsData[pluginId]
if !ok {
return false
return map[string]interface{}{
"enabled": false,
"version": "",
}
}
return state.Enable

return data
}

func (a *App) trackActivity() {
Expand Down Expand Up @@ -591,24 +595,14 @@ func (a *App) trackConfig() {
})

a.SendDiagnostic(TRACK_CONFIG_PLUGIN, map[string]interface{}{
"enable_antivirus": pluginActivated(cfg.PluginSettings.PluginStates, "antivirus"),
"enable_autolink": pluginActivated(cfg.PluginSettings.PluginStates, "mattermost-autolink"),
"enable_aws_sns": pluginActivated(cfg.PluginSettings.PluginStates, "com.mattermost.aws-sns"),
"enable_custom_user_attributes": pluginActivated(cfg.PluginSettings.PluginStates, "com.mattermost.custom-attributes"),
"enable_github": pluginActivated(cfg.PluginSettings.PluginStates, "github"),
"enable_gitlab": pluginActivated(cfg.PluginSettings.PluginStates, "com.github.manland.mattermost-plugin-gitlab"),
"enable_jenkins": pluginActivated(cfg.PluginSettings.PluginStates, "jenkins"),
"enable_jira": pluginActivated(cfg.PluginSettings.PluginStates, "jira"),
"enable_nps": pluginActivated(cfg.PluginSettings.PluginStates, "com.mattermost.nps"),
"enable_nps_survey": pluginSetting(&cfg.PluginSettings, "com.mattermost.nps", "enablesurvey", true),
"enable_welcome_bot": pluginActivated(cfg.PluginSettings.PluginStates, "com.mattermost.welcomebot"),
"enable_zoom": pluginActivated(cfg.PluginSettings.PluginStates, "zoom"),
"enable": *cfg.PluginSettings.Enable,
"enable_uploads": *cfg.PluginSettings.EnableUploads,
"allow_insecure_download_url": *cfg.PluginSettings.AllowInsecureDownloadUrl,
"enable_health_check": *cfg.PluginSettings.EnableHealthCheck,
"enable_marketplace": *cfg.PluginSettings.EnableMarketplace,
"is_default_marketplace_url": isDefault(*cfg.PluginSettings.MarketplaceUrl, model.PLUGIN_SETTINGS_DEFAULT_MARKETPLACE_URL),
"enable_nps_survey": pluginSetting(&cfg.PluginSettings, "com.mattermost.nps", "enablesurvey", true),
"enable": *cfg.PluginSettings.Enable,
"enable_uploads": *cfg.PluginSettings.EnableUploads,
"allow_insecure_download_url": *cfg.PluginSettings.AllowInsecureDownloadUrl,
"enable_health_check": *cfg.PluginSettings.EnableHealthCheck,
"enable_marketplace": *cfg.PluginSettings.EnableMarketplace,
"enable_remote_marketplace": *cfg.PluginSettings.EnableRemoteMarketplace,
"is_default_marketplace_url": isDefault(*cfg.PluginSettings.MarketplaceUrl, model.PLUGIN_SETTINGS_DEFAULT_MARKETPLACE_URL),
})

a.SendDiagnostic(TRACK_CONFIG_DATA_RETENTION, map[string]interface{}{
Expand Down Expand Up @@ -689,15 +683,19 @@ func (a *App) trackPlugins() {

pluginStates := a.Config().PluginSettings.PluginStates
plugins, _ := pluginsEnvironment.Available()
pluginTrackData := map[string]interface{}{}
marianunez marked this conversation as resolved.
Show resolved Hide resolved

if pluginStates != nil && plugins != nil {
for _, plugin := range plugins {
if plugin.Manifest == nil {
brokenManifestCount += 1
continue
}

enabled := false
if state, ok := pluginStates[plugin.Manifest.Id]; ok && state.Enable {
totalEnabledCount += 1
enabled = true
if plugin.Manifest.HasServer() {
backendEnabledCount += 1
}
Expand All @@ -716,6 +714,11 @@ func (a *App) trackPlugins() {
if plugin.Manifest.SettingsSchema != nil {
settingsCount += 1
}

pluginTrackData[plugin.Manifest.Id] = map[string]interface{}{
marianunez marked this conversation as resolved.
Show resolved Hide resolved
"enabled": enabled,
"version": plugin.Manifest.Version,
}
}
} else {
totalEnabledCount = -1 // -1 to indicate disabled or error
Expand All @@ -731,6 +734,16 @@ func (a *App) trackPlugins() {
"disabled_backend_plugins": backendDisabledCount,
"plugins_with_settings": settingsCount,
"plugins_with_broken_manifests": brokenManifestCount,
"enable_antivirus": pluginData(pluginTrackData, "antivirus"),
hanzei marked this conversation as resolved.
Show resolved Hide resolved
marianunez marked this conversation as resolved.
Show resolved Hide resolved
"enable_autolink": pluginData(pluginTrackData, "mattermost-autolink"),
"enable_aws_sns": pluginData(pluginTrackData, "com.mattermost.aws-sns"),
"enable_custom_user_attributes": pluginData(pluginTrackData, "com.mattermost.custom-attributes"),
"enable_github": pluginData(pluginTrackData, "github"),
"enable_gitlab": pluginData(pluginTrackData, "com.github.manland.mattermost-plugin-gitlab"),
"enable_jenkins": pluginData(pluginTrackData, "jenkins"),
"enable_jira": pluginData(pluginTrackData, "jira"),
"enable_nps": pluginData(pluginTrackData, "com.mattermost.nps"),
"enable_welcome_bot": pluginData(pluginTrackData, "com.mattermost.welcomebot"),
})
}

Expand Down
33 changes: 22 additions & 11 deletions app/diagnostics_test.go
Expand Up @@ -29,18 +29,29 @@ func TestPluginSetting(t *testing.T) {
assert.Equal(t, "asd", pluginSetting(settings, "test", "qwe", "asd"))
}

func TestPluginActivated(t *testing.T) {
states := map[string]*model.PluginState{
"foo": {
Enable: true,
},
"bar": {
Enable: false,
},
func TestPluginData(t *testing.T) {

fooPluginData := map[string]interface{}{
"enabled": true,
"version": "1.2.0",
}
barPluginData := map[string]interface{}{
"enabled": false,
"version": "0.1.2",
}
assert.True(t, pluginActivated(states, "foo"))
assert.False(t, pluginActivated(states, "bar"))
assert.False(t, pluginActivated(states, "none"))
unavailablePluginData := map[string]interface{}{
"enabled": false,
"version": "",
}

pluginsData := map[string]interface{}{
"foo": fooPluginData,
"bar": barPluginData,
}

assert.Equal(t, fooPluginData, pluginData(pluginsData, "foo"))
assert.Equal(t, barPluginData, pluginData(pluginsData, "bar"))
assert.Equal(t, unavailablePluginData, pluginData(pluginsData, "none"))
}

func TestDiagnostics(t *testing.T) {
Expand Down