From a632fee4a049973b320cec519e11fcc717037d80 Mon Sep 17 00:00:00 2001 From: sboring Date: Mon, 28 Aug 2023 12:35:21 -0700 Subject: [PATCH] Adding optional flag for values file similar to helm values file making CLI easier to use when multiple values need to be overridden --- cmd/liqoctl/cmd/install.go | 4 +- docs/installation/install.md | 4 +- pkg/liqoctl/install/handler.go | 67 ++++++++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/cmd/liqoctl/cmd/install.go b/cmd/liqoctl/cmd/install.go index cda28aa4f7..21b3a43aed 100644 --- a/cmd/liqoctl/cmd/install.go +++ b/cmd/liqoctl/cmd/install.go @@ -40,7 +40,7 @@ const liqoctlInstallLongHelp = `Install/upgrade Liqo in the selected cluster. This command wraps the Helm command to install/upgrade Liqo in the selected cluster, appropriately configuring it based on the provided flags. Additional -default values can be overridden through the --set flag. +default values can be overridden through the --values and or --set flag. Alternatively, it can be configured to only output a pre-configured values file, which can be further customized and used for a manual installation with Helm. @@ -160,6 +160,8 @@ func newInstallCommand(ctx context.Context, f *factory.Factory) *cobra.Command { // Using StringArray rather than StringSlice: splitting is left to the Helm library, which takes care of special cases (e.g., lists). cmd.PersistentFlags().StringArrayVar(&options.OverrideValues, "set", []string{}, "Set additional values on the command line (can specify multiple times or separate values with commas: key1=val1,key2=val2)") + cmd.PersistentFlags().StringArrayVar(&options.OverrideValuesFiles, "values", []string{}, + "Specify values in a YAML file or a URL (can specify multiple)") cmd.PersistentFlags().BoolVar(&options.DisableAPIServerSanityChecks, "disable-api-server-sanity-check", false, "Disable the sanity checks concerning the retrieved Kubernetes API server URL (default false)") cmd.PersistentFlags().BoolVar(&options.SkipValidation, "skip-validation", false, "Skip the validation of the arguments "+ diff --git a/docs/installation/install.md b/docs/installation/install.md index 2bd5d3c4e2..a50f959c6a 100644 --- a/docs/installation/install.md +++ b/docs/installation/install.md @@ -413,12 +413,12 @@ To change this behavior, check the [network flags](NetworkFlags). ## Customization options This section lists the main **customization parameters** supported by the *liqoctl install* command, along with a brief description. -Additionally, **all parameters** available in the Helm *values* file (the full list is provided in the dedicated [repository page](https://github.com/liqotech/liqo/tree/master/deployments/liqo)) can be modified through the `liqoctl install --set` flag, which supports the standard Helm syntax. +Additionally, **all parameters** available in the Helm *values* file (the full list is provided in the dedicated [repository page](https://github.com/liqotech/liqo/tree/master/deployments/liqo)) can be modified through the `liqoctl install --values` and or `liqoctl install --set` flags, which supports the standard Helm syntax. Finally, remember that: * You can type `liqoctl install --help` to get the list of available options. -* Some of the above parameters can be changed after installation by simply updating their value and re-applying the Helm chart, or by re-issuing the proper `liqoctl install --set [param=value]` command. However, given that not all parameters can be updated at run-time, please check that the command triggered the desired effect; a precise list of commands that can be changed at run-time is left for our future work. +* Some of the above parameters can be changed after installation by simply updating their value and re-applying the Helm chart, or by re-issuing the proper `liqoctl install --values [file] --set [param=value]` command. However, given that not all parameters can be updated at run-time, please check that the command triggered the desired effect; a precise list of commands that can be changed at run-time is left for our future work. ### Global diff --git a/pkg/liqoctl/install/handler.go b/pkg/liqoctl/install/handler.go index b7b4344fa2..7e33a8989d 100644 --- a/pkg/liqoctl/install/handler.go +++ b/pkg/liqoctl/install/handler.go @@ -18,7 +18,10 @@ import ( "context" "errors" "fmt" + "io" + "net/url" "os" + "path/filepath" "strings" "time" @@ -28,6 +31,8 @@ import ( "golang.org/x/mod/semver" "gopkg.in/yaml.v3" "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/repo" "helm.sh/helm/v3/pkg/strvals" corev1 "k8s.io/api/core/v1" @@ -66,9 +71,10 @@ type Options struct { RepoURL string ChartPath string - OverrideValues []string - chartValues map[string]interface{} - tmpDir string + OverrideValues []string + OverrideValuesFiles []string + chartValues map[string]interface{} + tmpDir string DryRun bool OnlyOutputValues bool @@ -162,6 +168,17 @@ func (o *Options) Run(ctx context.Context, provider Provider) error { return err } + valuesFiles, err := o.valuesFiles() + if err != nil { + s.Fail("Error generating installation parameters: ", output.PrettyErr(err)) + return err + } + values, err = util.MergeMaps(values, valuesFiles) + if err != nil { + s.Fail("Error generating installation parameters: ", output.PrettyErr(err)) + return err + } + for _, value := range o.OverrideValues { if err := strvals.ParseInto(value, values); err != nil { err := fmt.Errorf("failed parsing --set data: %w", err) @@ -398,6 +415,50 @@ func (o *Options) postProviderValues() map[string]interface{} { return values } +func (o *Options) valuesFiles() (map[string]interface{}, error) { + values := map[string]interface{}{} + // Near copy from Helm https://github.com/helm/helm/blob/eb4edc96c581c1978fe935197e20ced4071af5d5/pkg/cli/values/options.go#L48 + for _, filePath := range o.OverrideValuesFiles { + currentMap := map[string]interface{}{} + bytes, err := readFile(filePath, getter.All(cli.New())) + if err != nil { + return nil, err + } + + if err := yaml.Unmarshal(bytes, ¤tMap); err != nil { + return nil, err + } + // Merge with the previous map + values, err = util.MergeMaps(currentMap, values) + if err != nil { + return nil, err + } + } + return values, nil +} + +// copy from Helm https://github.com/helm/helm/blob/eb4edc96c581c1978fe935197e20ced4071af5d5/pkg/cli/values/options.go#L128 +func readFile(filePath string, p getter.Providers) ([]byte, error) { + if strings.TrimSpace(filePath) == "-" { + return io.ReadAll(os.Stdin) + } + u, err := url.Parse(filePath) + if err != nil { + return nil, err + } + + // FIXME: maybe someone handle other protocols like ftp. + g, err := p.ByScheme(u.Scheme) + if err != nil { + return os.ReadFile(filepath.Clean(filePath)) + } + data, err := g.Get(filePath, getter.WithURL(filePath)) + if err != nil { + return nil, err + } + return data.Bytes(), err +} + func (o *Options) cleanup() error { if o.tmpDir != "" { return os.RemoveAll(o.tmpDir)