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

Support Activating plugins on Plugin Group Publish/Activation #794

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkg/constants/env_variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,8 @@ const (
// UseStableKubeContextNameForTanzuContext uses the stable kube context name associated with tanzu context.
// CLI would not change the context name when the TAP resource pointed by the CLI context is changed.
UseStableKubeContextNameForTanzuContext = "TANZU_CLI_USE_STABLE_KUBE_CONTEXT_NAME"

// ActivatePluginsOnPluginGroupPublish activates all the plugins specified within the plugin group
// as part of the plugin group publishing
ActivatePluginsOnPluginGroupPublish = "TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH"
marckhouzam marked this conversation as resolved.
Show resolved Hide resolved
)
59 changes: 48 additions & 11 deletions pkg/plugininventory/sqlite_inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ func (b *SQLiteInventory) InsertPlugin(pluginInventoryEntry *PluginInventoryEntr

// InsertPluginGroup inserts plugin-group to the inventory
// specifying override will delete the existing plugin-group and add new one
func (b *SQLiteInventory) InsertPluginGroup(pg *PluginGroup, override bool) error {
func (b *SQLiteInventory) InsertPluginGroup(pg *PluginGroup, override bool) error { //nolint:gocyclo
db, err := sql.Open("sqlite", b.inventoryFile)
if err != nil {
return errors.Wrapf(err, "failed to open the DB from '%s' file", b.inventoryFile)
Expand Down Expand Up @@ -674,7 +674,14 @@ func (b *SQLiteInventory) InsertPluginGroup(pg *PluginGroup, override bool) erro
}
}

allowHiddenPlugins, _ := strconv.ParseBool(os.Getenv(constants.ConfigVariableIncludeDeactivatedPluginsForTesting))
includeDeactivatedPluginsForTesting, _ := strconv.ParseBool(os.Getenv(constants.ConfigVariableIncludeDeactivatedPluginsForTesting))
// Only activate plugins if TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH=true and we are PluginGroup is also active (!pg.Hidden)
activatePlugins, _ := strconv.ParseBool(os.Getenv(constants.ActivatePluginsOnPluginGroupPublish))
marckhouzam marked this conversation as resolved.
Show resolved Hide resolved
activatePlugins = activatePlugins && !pg.Hidden

// Allow hidden plugins if either of the below configuration is specified
allowHiddenPlugins := includeDeactivatedPluginsForTesting || activatePlugins

for version, plugins := range pg.Versions {
for _, pi := range plugins {
// Skip plugin group verification. If TANZU_CLI_SKIP_PLUGIN_GROUP_VERIFICATION_ON_PUBLISH is set while publishing a plugin-group
Expand All @@ -692,6 +699,16 @@ func (b *SQLiteInventory) InsertPluginGroup(pg *PluginGroup, override bool) erro
}
}

// Activate plugins on plugin group publish if the TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH
// environment variable is set to True.
// Note: If it is set to false, plugins won't be deactivated
if activatePlugins {
err = b.updatePluginVersionActivationState(db, pi.Name, string(pi.Target), pi.Version, true)
if err != nil {
return errors.Wrap(err, "unable to activate plugin with in plugin group")
marckhouzam marked this conversation as resolved.
Show resolved Hide resolved
}
}

row := groupDBRow{
vendor: pg.Vendor,
publisher: pg.Publisher,
Expand Down Expand Up @@ -724,18 +741,25 @@ func (b *SQLiteInventory) UpdatePluginActivationState(pluginInventoryEntry *Plug
defer db.Close()

for version := range pluginInventoryEntry.Artifacts {
result, err := db.Exec("UPDATE PluginBinaries SET hidden = ? WHERE PluginName = ? AND Target = ? AND Version = ? AND Publisher = ? AND Vendor = ? ;", strconv.FormatBool(pluginInventoryEntry.Hidden), pluginInventoryEntry.Name, string(pluginInventoryEntry.Target), version, pluginInventoryEntry.Publisher, pluginInventoryEntry.Vendor)
err := b.updatePluginVersionActivationState(db, pluginInventoryEntry.Name, string(pluginInventoryEntry.Target), version, !pluginInventoryEntry.Hidden)
if err != nil {
return errors.Wrapf(err, "unable to update plugin %v_%v", pluginInventoryEntry.Name, string(pluginInventoryEntry.Target))
return err
}
rowsAffected, _ := result.RowsAffected()
if rowsAffected == 0 {
return errors.Errorf("unable to update plugin %v_%v", pluginInventoryEntry.Name, string(pluginInventoryEntry.Target))
}
// Write sql statement logs if required
writeSQLStatementLogs(fmt.Sprintf("UPDATE PluginBinaries SET hidden = %v WHERE PluginName = %v AND Target = %v AND Version = %v AND Publisher = %v AND Vendor = %v ;\n", strconv.FormatBool(pluginInventoryEntry.Hidden), pluginInventoryEntry.Name, string(pluginInventoryEntry.Target), version, pluginInventoryEntry.Publisher, pluginInventoryEntry.Vendor))
}
return nil
}

func (b *SQLiteInventory) updatePluginVersionActivationState(db *sql.DB, name, target, version string, activate bool) error {
result, err := db.Exec("UPDATE PluginBinaries SET hidden = ? WHERE PluginName = ? AND Target = ? AND Version = ? ;", strconv.FormatBool(!activate), name, target, version)
if err != nil {
return errors.Wrapf(err, "unable to update plugin %v_%v", name, target)
}
rowsAffected, _ := result.RowsAffected()
if rowsAffected == 0 {
return errors.Errorf("unable to update plugin %v_%v", name, target)
}
// Write sql statement logs if required
writeSQLStatementLogs(fmt.Sprintf("UPDATE PluginBinaries SET hidden = %v WHERE PluginName = %v AND Target = %v AND Version = %v ;\n", strconv.FormatBool(!activate), name, target, version))
return nil
}

Expand All @@ -746,7 +770,20 @@ func (b *SQLiteInventory) UpdatePluginGroupActivationState(pg *PluginGroup) erro
}
defer db.Close()

for version := range pg.Versions {
activatePlugins, _ := strconv.ParseBool(os.Getenv(constants.ActivatePluginsOnPluginGroupPublish))

for version, plugins := range pg.Versions {
// Activate plugins on plugin group activate if the TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH
// environment variable is set to `True` and we are trying to activate the plugin group
if activatePlugins && !pg.Hidden {
for _, pi := range plugins {
err = b.updatePluginVersionActivationState(db, pi.Name, string(pi.Target), pi.Version, true)
if err != nil {
return errors.Wrap(err, "unable to activate plugin within plugin group")
}
}
}

result, err := db.Exec("UPDATE PluginGroups SET hidden = ? WHERE GroupName = ? AND Publisher = ? AND Vendor = ? AND GroupVersion = ? ;", strconv.FormatBool(pg.Hidden), pg.Name, pg.Publisher, pg.Vendor, version)
if err != nil {
return errors.Wrapf(err, "unable to update plugin-group '%s:%s'", PluginGroupToID(pg), version)
Expand Down
124 changes: 114 additions & 10 deletions pkg/plugininventory/sqlite_inventory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,44 @@ var _ = Describe("Unit tests for plugin inventory", func() {
Expect(plugins[0].Version).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Version))
Expect(plugins[0].Mandatory).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Mandatory))
})
It("should not return error if TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH=true and Plugins should be activated", func() {
err = os.Setenv(constants.ActivatePluginsOnPluginGroupPublish, "true")
defer os.Unsetenv(constants.ActivatePluginsOnPluginGroupPublish)
Expect(err).To(BeNil())

err = inventory.InsertPluginGroup(&groupWithHiddenPlugin, false)
Expect(err).To(BeNil())

groups, err := inventory.GetPluginGroups(PluginGroupFilter{})
Expect(err).ToNot(HaveOccurred())
Expect(len(groups)).To(Equal(1))
pg := groups[0]
Expect(pg.Name).To(Equal(groupWithHiddenPlugin.Name))
Expect(pg.Vendor).To(Equal(groupWithHiddenPlugin.Vendor))
Expect(pg.Publisher).To(Equal(groupWithHiddenPlugin.Publisher))
Expect(pg.Description).To(Equal(groupWithHiddenPlugin.Description))

Expect(pg.Hidden).To(Equal(groupWithHiddenPlugin.Hidden))

Expect(len(pg.Versions)).To(Equal(1))

plugins := pg.Versions["v1.0.0"]
Expect(len(plugins)).To(Equal(1))
Expect(plugins[0].Name).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Name))
Expect(plugins[0].Target).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Target))
Expect(plugins[0].Version).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Version))
Expect(plugins[0].Mandatory).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Mandatory))

// Try to get the plugin with IncludeHidden:false filter and verify that
// plugin that was deactivated before creating plugin group is now activated
updatedPlugins, err := inventory.GetPlugins(&PluginInventoryFilter{Name: plugins[0].Name, Target: plugins[0].Target, Version: plugins[0].Version, IncludeHidden: false})
Expect(err).ToNot(HaveOccurred())
Expect(len(updatedPlugins)).To(Equal(1))
Expect(updatedPlugins[0].Name).To(Equal(plugins[0].Name))
Expect(updatedPlugins[0].Target).To(Equal(plugins[0].Target))
Expect(updatedPlugins[0].RecommendedVersion).To(Equal(plugins[0].Version))
Expect(updatedPlugins[0].Hidden).To(BeFalse())
})
})
Context("When inserting a plugin-group which already exists in the database", func() {
BeforeEach(func() {
Expand Down Expand Up @@ -1581,6 +1619,8 @@ var _ = Describe("Unit tests for plugin inventory", func() {
Expect(err).To(BeNil(), "failed to insert plugin2")
err = inventory.InsertPlugin(&piEntry3)
Expect(err).To(BeNil(), "failed to insert plugin3")
err = inventory.InsertPlugin(&hiddenPluginEntry)
Expect(err).To(BeNil(), "failed to insert hidden-plugin")
})
AfterEach(func() {
os.RemoveAll(tmpDir)
Expand All @@ -1591,7 +1631,7 @@ var _ = Describe("Unit tests for plugin inventory", func() {
err = inventory.InsertPluginGroup(&pluginGroup1, false)
Expect(err).To(BeNil())
})
It("should not return error when no change has been done to the activation state and the GetPluginGroups should reflect the same", func() {
It("should not return error when no change has been done to the activation state and plugin group should still be active and the GetPluginGroups should reflect the same", func() {
err = inventory.UpdatePluginGroupActivationState(&pluginGroup1)
Expect(err).To(BeNil())

Expand All @@ -1608,8 +1648,35 @@ var _ = Describe("Unit tests for plugin inventory", func() {
Expect(len(groups[0].Versions["v2.0.0"])).To(Equal(len(pluginGroup1.Versions["v2.0.0"])))
Expect(len(groups[0].Versions["v1.0.0"])).To(Equal(len(pluginGroup1.Versions["v1.0.0"])))
})
It("should not return error when the activation state has been updated and the GetPluginGroups should reflect the change", func() {
It("should not return error when the plugin group is deactivated and the GetPluginGroups should not return the plugin group", func() {
pluginGroupUpdated := pluginGroup1
pluginGroupUpdated.Hidden = true
err = inventory.UpdatePluginGroupActivationState(&pluginGroupUpdated)
Expect(err).To(BeNil())

// Verify the result using GetPluginGroups
groups, err := inventory.GetPluginGroups(PluginGroupFilter{})
Expect(err).ToNot(HaveOccurred())
Expect(len(groups)).To(Equal(0))
})
})

Context("When updating the activation state of a plugin-group wrt TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH env variable", func() {
BeforeEach(func() {
err = os.Setenv(constants.ConfigVariableIncludeDeactivatedPluginsForTesting, "true")
defer os.Unsetenv(constants.ConfigVariableIncludeDeactivatedPluginsForTesting)
hiddenGroupWithHiddenPlugin := groupWithHiddenPlugin
hiddenGroupWithHiddenPlugin.Hidden = true
Expect(err).To(BeNil())
err = inventory.InsertPluginGroup(&hiddenGroupWithHiddenPlugin, false)
Expect(err).To(BeNil())
})
It("when activating plugin group containing a deactivated plugin with TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH=true set, it should activate the deactivated plugin", func() {
err = os.Setenv(constants.ActivatePluginsOnPluginGroupPublish, "true")
defer os.Unsetenv(constants.ActivatePluginsOnPluginGroupPublish)
Expect(err).To(BeNil())

pluginGroupUpdated := groupWithHiddenPlugin
pluginGroupUpdated.Hidden = false
err = inventory.UpdatePluginGroupActivationState(&pluginGroupUpdated)
Expect(err).To(BeNil())
Expand All @@ -1618,14 +1685,51 @@ var _ = Describe("Unit tests for plugin inventory", func() {
groups, err := inventory.GetPluginGroups(PluginGroupFilter{})
Expect(err).ToNot(HaveOccurred())
Expect(len(groups)).To(Equal(1))
Expect(groups[0].Name).To(Equal(pluginGroupUpdated.Name))
Expect(groups[0].Vendor).To(Equal(pluginGroupUpdated.Vendor))
Expect(groups[0].Publisher).To(Equal(pluginGroupUpdated.Publisher))
Expect(groups[0].Description).To(Equal(pluginGroupUpdated.Description))
Expect(groups[0].Hidden).To(Equal(pluginGroupUpdated.Hidden))
Expect(len(groups[0].Versions)).To(Equal(len(pluginGroup1.Versions)))
Expect(len(groups[0].Versions["v2.0.0"])).To(Equal(len(pluginGroup1.Versions["v2.0.0"])))
Expect(len(groups[0].Versions["v1.0.0"])).To(Equal(len(pluginGroup1.Versions["v1.0.0"])))
pg := groups[0]
// Make sure the hidden field is set to correct value we requested
Expect(pg.Hidden).To(Equal(groupWithHiddenPlugin.Hidden))
Expect(len(pg.Versions)).To(Equal(1))

plugins := pg.Versions["v1.0.0"]
Expect(len(plugins)).To(Equal(1))
Expect(plugins[0].Name).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Name))
Expect(plugins[0].Target).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Target))
Expect(plugins[0].Version).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Version))
Expect(plugins[0].Mandatory).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Mandatory))

// Try to get the plugin with IncludeHidden:false filter and verify that
// plugin that was deactivated before activating the plugin group is not activated
updatedPlugins, err := inventory.GetPlugins(&PluginInventoryFilter{Name: plugins[0].Name, Target: plugins[0].Target, Version: plugins[0].Version, IncludeHidden: false})
Expect(err).ToNot(HaveOccurred())
Expect(len(updatedPlugins)).To(Equal(1))
Expect(updatedPlugins[0].Name).To(Equal(plugins[0].Name))
Expect(updatedPlugins[0].Target).To(Equal(plugins[0].Target))
Expect(updatedPlugins[0].RecommendedVersion).To(Equal(plugins[0].Version))
Expect(updatedPlugins[0].Hidden).To(BeFalse())
})
It("when activating plugin group containing a deactivated plugin without TANZU_CLI_ACTIVATE_PLUGINS_ON_PLUGIN_GROUP_PUBLISH being set, it should NOT activate the deactivated plugin", func() {
pluginGroupUpdated := groupWithHiddenPlugin
pluginGroupUpdated.Hidden = false
err = inventory.UpdatePluginGroupActivationState(&pluginGroupUpdated)
Expect(err).To(BeNil())

// Verify the result using GetPluginGroups
groups, err := inventory.GetPluginGroups(PluginGroupFilter{})
Expect(err).ToNot(HaveOccurred())
Expect(len(groups)).To(Equal(1))
pg := groups[0]

plugins := pg.Versions["v1.0.0"]
Expect(len(plugins)).To(Equal(1))
Expect(plugins[0].Name).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Name))
Expect(plugins[0].Target).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Target))
Expect(plugins[0].Version).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Version))
Expect(plugins[0].Mandatory).To(Equal(groupWithHiddenPlugin.Versions["v1.0.0"][0].Mandatory))

// Try to get the plugin with IncludeHidden:false filter and no plugins should be present
plugins2, err := inventory.GetPlugins(&PluginInventoryFilter{Name: plugins[0].Name, Target: plugins[0].Target, Version: plugins[0].Version, IncludeHidden: false})
Expect(err).ToNot(HaveOccurred())
Expect(len(plugins2)).To(Equal(0))
})
})

Expand Down
Loading