Skip to content

Commit 5c410ea

Browse files
committed
[deckhouse-cli] feat: Enhance plugin management with requirements checking
Signed-off-by: Smyslov Maxim <maksim.smyslov@flant.com>
1 parent 116f220 commit 5c410ea

File tree

2 files changed

+78
-14
lines changed

2 files changed

+78
-14
lines changed

cmd/plugins/plugins.go

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -175,23 +175,12 @@ func (pc *PluginsCommand) fetchInstalledPlugins() ([]pluginDisplayInfo, error) {
175175
res := make([]pluginDisplayInfo, 0, len(plugins))
176176

177177
for _, plugin := range plugins {
178-
pluginBinaryPath := path.Join(pc.pluginDirectory, "plugins", plugin.Name(), "current")
179-
cmd := exec.Command(pluginBinaryPath, "--version")
180-
181-
output, err := cmd.Output()
178+
version, err := pc.getInstalledPluginVersion(plugin.Name())
182179
if err != nil {
183180
res = append(res, pluginDisplayInfo{
184181
Name: plugin.Name(),
185-
Description: "failed to call plugin",
186-
})
187-
continue
188-
}
189-
190-
version, err := semver.NewVersion(strings.TrimSpace(string(output)))
191-
if err != nil {
192-
res = append(res, pluginDisplayInfo{
193-
Name: plugin.Name(),
194-
Description: "failed to parse version",
182+
Version: "ERROR",
183+
Description: err.Error(),
195184
})
196185
continue
197186
}
@@ -590,6 +579,12 @@ func (pc *PluginsCommand) installPlugin(ctx context.Context, pluginName string,
590579
fmt.Printf("Plugin: %s %s\n", plugin.Name, plugin.Version)
591580
fmt.Printf("Description: %s\n", plugin.Description)
592581

582+
// validate requirements
583+
err = pc.validateRequirements(plugin)
584+
if err != nil {
585+
return fmt.Errorf("failed to validate requirements: %w", err)
586+
}
587+
593588
// check if binary exists (if yes - rename it to .old)
594589
// example path: /opt/deckhouse/lib/deckhouse-cli/plugins/example-plugin/v1/example-plugin
595590
pluginBinaryPath := path.Join(versionDir, pluginName)
@@ -819,3 +814,65 @@ func (pc *PluginsCommand) pluginsRemoveAllCommand() *cobra.Command {
819814

820815
return cmd
821816
}
817+
818+
func (pc *PluginsCommand) getInstalledPluginVersion(pluginName string) (*semver.Version, error) {
819+
pluginBinaryPath := path.Join(pc.pluginDirectory, "plugins", pluginName, "current")
820+
cmd := exec.Command(pluginBinaryPath, "--version")
821+
822+
output, err := cmd.Output()
823+
if err != nil {
824+
return nil, fmt.Errorf("failed to call plugin: %w", err)
825+
}
826+
827+
version, err := semver.NewVersion(strings.TrimSpace(string(output)))
828+
if err != nil {
829+
return nil, fmt.Errorf("failed to parse version: %w", err)
830+
}
831+
832+
return version, nil
833+
}
834+
835+
func (pc *PluginsCommand) validateRequirements(plugin *internal.Plugin) error {
836+
err := pc.validatePluginRequirement(plugin)
837+
if err != nil {
838+
return fmt.Errorf("failed to validate plugin requirement: %w", err)
839+
}
840+
841+
// err = pc.validateModuleRequirement(plugin)
842+
// if err != nil {
843+
// return fmt.Errorf("failed to validate module requirement: %w", err)
844+
// }
845+
846+
return nil
847+
}
848+
849+
func (pc *PluginsCommand) validatePluginRequirement(plugin *internal.Plugin) error {
850+
for _, pluginRequirement := range plugin.Requirements.Plugins {
851+
installed, err := pc.checkInstalled(pluginRequirement.Name)
852+
if err != nil {
853+
return fmt.Errorf("failed to check if plugin is installed: %w", err)
854+
}
855+
if !installed {
856+
return fmt.Errorf("plugin %s is not installed", pluginRequirement.Name)
857+
}
858+
859+
// check constraint
860+
if pluginRequirement.Constraint != "" {
861+
installedVersion, err := pc.getInstalledPluginVersion(pluginRequirement.Name)
862+
if err != nil {
863+
return fmt.Errorf("failed to get installed version: %w", err)
864+
}
865+
866+
constraint, err := semver.NewConstraint(pluginRequirement.Constraint)
867+
if err != nil {
868+
return fmt.Errorf("failed to parse constraint: %w", err)
869+
}
870+
871+
if !constraint.Check(installedVersion) {
872+
return fmt.Errorf("plugin %s version %s does not satisfy constraint %s", pluginRequirement.Name, plugin.Version, pluginRequirement.Constraint)
873+
}
874+
}
875+
}
876+
877+
return nil
878+
}

internal/plugin.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type Flag struct {
4040
type Requirements struct {
4141
Kubernetes KubernetesRequirement
4242
Modules []ModuleRequirement
43+
Plugins []PluginRequirement
4344
}
4445

4546
// KubernetesRequirement represents Kubernetes version constraint
@@ -52,3 +53,9 @@ type ModuleRequirement struct {
5253
Name string
5354
Constraint string
5455
}
56+
57+
// PluginRequirement represents a required plugin
58+
type PluginRequirement struct {
59+
Name string
60+
Constraint string
61+
}

0 commit comments

Comments
 (0)