-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #105 from replicatedhq/installer-ls
Adding "installer ls" and "installer create" commands to CLI
- Loading branch information
Showing
21 changed files
with
541 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func (r *runners) InitInstallerCommand(parent *cobra.Command) *cobra.Command { | ||
installerCommand := &cobra.Command{ | ||
Use: "installer", | ||
Short: "Manage Kubernetes installers", | ||
Long: `The installers command allows vendors to create, display, modify and promote kurl.sh specs for managing the installation of Kubernetes.`, | ||
} | ||
parent.AddCommand(installerCommand) | ||
|
||
return installerCommand | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
"io/ioutil" | ||
) | ||
|
||
func (r *runners) InitInstallerCreate(parent *cobra.Command) { | ||
cmd := &cobra.Command{ | ||
Use: "create", | ||
Short: "Create a new installer spec", | ||
Long: `Create a new installer spec by providing YAML configuration for a https://kurl.sh cluster.`, | ||
} | ||
|
||
parent.AddCommand(cmd) | ||
|
||
cmd.Flags().StringVar(&r.args.createInstallerYaml, "yaml", "", "The YAML config for this installer. Use '-' to read from stdin. Cannot be used with the `yaml-file` falg.") | ||
cmd.Flags().StringVar(&r.args.createInstallerYamlFile, "yaml-file", "", "The file name with YAML config for this installer. Cannot be used with the `yaml` flag.") | ||
cmd.Flags().StringVar(&r.args.createInstallerPromote, "promote", "", "Channel name or id to promote this installer to") | ||
cmd.Flags().BoolVar(&r.args.createInstallerPromoteEnsureChannel, "ensure-channel", false, "When used with --promote <channel>, will create the channel if it doesn't exist") | ||
|
||
cmd.RunE = r.installerCreate | ||
} | ||
|
||
func (r *runners) installerCreate(_ *cobra.Command, _ []string) error { | ||
if r.appType != "kots" { | ||
return errors.Errorf("Installer specs are only supported for KOTS applications, app %q has type %q", r.appID, r.appType) | ||
} | ||
|
||
if r.args.createInstallerYaml == "" && | ||
r.args.createInstallerYamlFile == "" { | ||
return errors.New("one of --yaml, --yaml-file is required") | ||
} | ||
|
||
// can't ensure a channel if you didn't pass one | ||
if r.args.createInstallerPromoteEnsureChannel && r.args.createInstallerPromote == "" { | ||
return errors.New("cannot use the flag --ensure-channel without also using --promote <channel> ") | ||
} | ||
|
||
if r.args.createInstallerYaml != "" && r.args.createInstallerYamlFile != "" { | ||
return errors.New("only one of --yaml or --yaml-file may be specified") | ||
} | ||
|
||
if r.args.createInstallerYaml == "-" { | ||
bytes, err := ioutil.ReadAll(r.stdin) | ||
if err != nil { | ||
return errors.Wrap(err, "read from stdin") | ||
} | ||
r.args.createInstallerYaml = string(bytes) | ||
} | ||
|
||
if r.args.createInstallerYamlFile != "" { | ||
bytes, err := ioutil.ReadFile(r.args.createInstallerYamlFile) | ||
if err != nil { | ||
return errors.Wrap(err, "read file yaml") | ||
} | ||
r.args.createInstallerYaml = string(bytes) | ||
} | ||
|
||
// if the --promote param was used make sure it identifies exactly one | ||
// channel before proceeding | ||
var promoteChanID string | ||
if r.args.createInstallerPromote != "" { | ||
var err error | ||
promoteChanID, err = r.getOrCreateChannelForPromotion( | ||
r.args.createInstallerPromote, | ||
r.args.createInstallerPromoteEnsureChannel, | ||
) | ||
if err != nil { | ||
return errors.Wrapf(err, "get or create channel %q for promotion", promoteChanID) | ||
} | ||
} | ||
|
||
installerSpec, err := r.api.CreateInstaller(r.appID, r.appType, r.args.createInstallerYaml) | ||
if err != nil { | ||
return errors.Wrap(err, "create installer") | ||
} | ||
|
||
if _, err := fmt.Fprintf(r.w, "SEQUENCE: %d\n", installerSpec.Sequence); err != nil { | ||
return errors.Wrap(err, "print sequence to r.w") | ||
} | ||
r.w.Flush() | ||
|
||
// don't send a version label as its not really meaningful | ||
noVersionLabel := "" | ||
|
||
if promoteChanID != "" { | ||
if err := r.api.PromoteInstaller( | ||
r.appID, | ||
r.appType, | ||
installerSpec.Sequence, | ||
promoteChanID, | ||
noVersionLabel, | ||
); err != nil { | ||
return errors.Wrap(err, "promote installer") | ||
} | ||
|
||
// ignore error since operation was successful | ||
fmt.Fprintf(r.w, "Channel %s successfully set to release %d\n", promoteChanID, installerSpec.Sequence) | ||
r.w.Flush() | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/replicatedhq/replicated/cli/print" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func (r *runners) InitInstallerList(parent *cobra.Command) { | ||
cmd := &cobra.Command{ | ||
Use: "ls", | ||
Short: "List an app's Kubernetes Installers", | ||
Long: "List an app's https://kurl.sh Kubernetes Installers", | ||
} | ||
|
||
parent.AddCommand(cmd) | ||
cmd.RunE = r.installerList | ||
} | ||
|
||
func (r *runners) installerList(_ *cobra.Command, _ []string) error { | ||
installers, err := r.api.ListInstallers(r.appID, r.appType) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return print.Installers(r.w, installers) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package print | ||
|
||
import ( | ||
"github.com/replicatedhq/replicated/pkg/types" | ||
"strings" | ||
"text/tabwriter" | ||
"text/template" | ||
) | ||
|
||
var installersTmplSrc = `SEQUENCE CREATED ACTIVE_CHANNELS | ||
{{ range . -}} | ||
{{ .Sequence }} {{ time .CreatedAt.Time }} {{ .ActiveChannels }} | ||
{{ end }}` | ||
|
||
var installersTmpl = template.Must(template.New("Installers").Funcs(funcs).Parse(installersTmplSrc)) | ||
|
||
func Installers(w *tabwriter.Writer, appReleases []types.InstallerSpec) error { | ||
rs := make([]map[string]interface{}, len(appReleases)) | ||
|
||
for i, r := range appReleases { | ||
// join active channel names like "Stable,Unstable" | ||
activeChans := make([]string, len(r.ActiveChannels)) | ||
for j, activeChan := range r.ActiveChannels { | ||
activeChans[j] = activeChan.Name | ||
} | ||
activeChansField := strings.Join(activeChans, ",") | ||
|
||
rs[i] = map[string]interface{}{ | ||
"Sequence": r.Sequence, | ||
"CreatedAt": r.CreatedAt, | ||
"ActiveChannels": activeChansField, | ||
} | ||
} | ||
|
||
if err := installersTmpl.Execute(w, rs); err != nil { | ||
return err | ||
} | ||
|
||
return w.Flush() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package client | ||
|
||
import ( | ||
"github.com/pkg/errors" | ||
"github.com/replicatedhq/replicated/pkg/types" | ||
) | ||
|
||
func (c *Client) CreateInstaller(appId string, appType string, yaml string) (*types.InstallerSpec, error) { | ||
if appType == "platform" { | ||
return nil, errors.Errorf("Kubernetes Installers are not supported for platform applications") | ||
} else if appType == "ship" { | ||
return nil, errors.Errorf("Kubernetes Installers are not supported for platfrom applications") | ||
} else if appType == "kots" { | ||
return c.KotsClient.CreateInstaller(appId, yaml) | ||
} | ||
|
||
return nil, errors.New("unknown app type") | ||
} | ||
|
||
func (c *Client) ListInstallers(appId string, appType string) ([]types.InstallerSpec, error) { | ||
|
||
if appType == "platform" { | ||
return nil, errors.Errorf("Kubernetes Installers are not supported for platform applications") | ||
} else if appType == "ship" { | ||
return nil, errors.Errorf("Kubernetes Installers are not supported for platform applications") | ||
} else if appType == "kots" { | ||
return c.KotsClient.ListInstallers(appId) | ||
} | ||
|
||
return nil, errors.New("unknown app type") | ||
|
||
} | ||
|
||
func (c *Client) PromoteInstaller(appId string, appType string, sequence int64, channelID string, versionLabel string) error { | ||
if appType == "platform" { | ||
return errors.Errorf("Kubernetes Installers are not supported for platform applications") | ||
} else if appType == "ship" { | ||
return errors.Errorf("Kubernetes Installers are not supported for ship applications") | ||
} else if appType == "kots" { | ||
return c.KotsClient.PromoteInstaller(appId, sequence, channelID, versionLabel) | ||
} | ||
|
||
return errors.New("unknown app type") | ||
|
||
} |
Oops, something went wrong.