forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
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 openshift#786 from ironcladlou/rollback-cli
Merged by openshift-bot
- Loading branch information
Showing
10 changed files
with
345 additions
and
61 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
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,108 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
kubectl "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl" | ||
kcmd "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd" | ||
|
||
describe "github.com/openshift/origin/pkg/cmd/cli/describe" | ||
deployapi "github.com/openshift/origin/pkg/deploy/api" | ||
) | ||
|
||
const rollbackLongDesc = ` | ||
Revert part of an application back to a previous deployment. | ||
When you run this command your deployment configuration will be updated to match | ||
the provided deployment. By default only the pod and container configuration | ||
will be changed and scaling or trigger settings will be left as-is. Note that | ||
environment variables and volumes are included in rollbacks, so if you've | ||
recently updated security credentials in your environment your previous | ||
deployment may not have the correct values. | ||
If you would like to review the outcome of the rollback, pass '--dry-run' to print | ||
a human-readable representation of the updated deployment configuration instead of | ||
executing the rollback. This is useful if you're not quite sure what the outcome | ||
will be. | ||
Examples: | ||
Perform a rollback: | ||
$ %[1]s %[2]s deployment-1 | ||
See what the rollback will look like, but don't perform the rollback: | ||
$ %[1]s %[2]s deployment-1 --dry-run | ||
Perform the rollback manually by piping the JSON of the new config back to %[1]s: | ||
$ %[1]s %[2]s deployment-1 --output=json | %[1]s update deploymentConfigs deployment -f - | ||
` | ||
|
||
func NewCmdRollback(parentName string, name string, f *Factory, out io.Writer) *cobra.Command { | ||
rollback := &deployapi.DeploymentConfigRollback{ | ||
Spec: deployapi.DeploymentConfigRollbackSpec{ | ||
IncludeTemplate: true, | ||
}, | ||
} | ||
|
||
cmd := &cobra.Command{ | ||
Use: fmt.Sprintf("%s <from-deployment>", name), | ||
Short: "Revert part of an application back to a previous deployment.", | ||
Long: fmt.Sprintf(rollbackLongDesc, parentName, name), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
if len(args) == 0 || len(args[0]) == 0 { | ||
usageError(cmd, "A deployment name is required.") | ||
} | ||
|
||
rollback.Spec.From.Name = args[0] | ||
|
||
outputFormat := kcmd.GetFlagString(cmd, "output") | ||
outputTemplate := kcmd.GetFlagString(cmd, "template") | ||
dryRun := kcmd.GetFlagBool(cmd, "dry-run") | ||
|
||
osClient, _, err := f.Clients(cmd) | ||
checkErr(err) | ||
|
||
namespace := getOriginNamespace(cmd) | ||
|
||
// Generate the rollback config | ||
newConfig, err := osClient.DeploymentConfigs(namespace).Rollback(rollback) | ||
checkErr(err) | ||
|
||
// If dry-run is specified, describe the rollback and exit | ||
if dryRun { | ||
describer := describe.NewDeploymentConfigDescriberForConfig(newConfig) | ||
description, descErr := describer.Describe(newConfig.Namespace, newConfig.Name) | ||
checkErr(descErr) | ||
out.Write([]byte(description)) | ||
return | ||
} | ||
|
||
// If an output format is specified, display the rollback config JSON and exit | ||
// WITHOUT performing a rollback. | ||
if len(outputFormat) > 0 { | ||
printer, _, perr := kubectl.GetPrinter(outputFormat, outputTemplate) | ||
checkErr(perr) | ||
printer.PrintObj(newConfig, out) | ||
return | ||
} | ||
|
||
// Apply the rollback config | ||
_, updateErr := osClient.DeploymentConfigs(namespace).Update(newConfig) | ||
checkErr(updateErr) | ||
}, | ||
} | ||
|
||
cmd.Flags().BoolVar(&rollback.Spec.IncludeTriggers, "change-triggers", false, "Include the previous deployment's triggers in the rollback") | ||
cmd.Flags().BoolVar(&rollback.Spec.IncludeStrategy, "change-strategy", false, "Include the previous deployment's strategy in the rollback") | ||
cmd.Flags().BoolVar(&rollback.Spec.IncludeReplicationMeta, "change-scaling-settings", false, "Include the previous deployment's replicationController replica count and selector in the rollback") | ||
cmd.Flags().BoolP("dry-run", "d", false, "Instead of performing the rollback, describe what the rollback will look like in human-readable form") | ||
cmd.Flags().StringP("output", "o", "", "Instead of performing the rollback, print the updated deployment configuration in the specified format (json|yaml|template|templatefile)") | ||
cmd.Flags().StringP("template", "t", "", "Template string or path to template file to use when -o=template or -o=templatefile.") | ||
|
||
return cmd | ||
} |
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,160 @@ | ||
package describe | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"strconv" | ||
"strings" | ||
"text/tabwriter" | ||
|
||
kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api" | ||
|
||
"github.com/openshift/origin/pkg/client" | ||
deployapi "github.com/openshift/origin/pkg/deploy/api" | ||
) | ||
|
||
// DeploymentConfigDescriber generates information about a DeploymentConfig | ||
type DeploymentConfigDescriber struct { | ||
client deploymentDescriberClient | ||
} | ||
|
||
type deploymentDescriberClient interface { | ||
GetDeploymentConfig(namespace, name string) (*deployapi.DeploymentConfig, error) | ||
} | ||
|
||
type genericDeploymentDescriberClient struct { | ||
getDeploymentConfig func(namespace, name string) (*deployapi.DeploymentConfig, error) | ||
} | ||
|
||
func (c *genericDeploymentDescriberClient) GetDeploymentConfig(namespace, name string) (*deployapi.DeploymentConfig, error) { | ||
return c.getDeploymentConfig(namespace, name) | ||
} | ||
|
||
func NewDeploymentConfigDescriberForConfig(config *deployapi.DeploymentConfig) *DeploymentConfigDescriber { | ||
return &DeploymentConfigDescriber{ | ||
client: &genericDeploymentDescriberClient{ | ||
getDeploymentConfig: func(namespace, name string) (*deployapi.DeploymentConfig, error) { | ||
return config, nil | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func NewDeploymentConfigDescriber(client client.Interface) *DeploymentConfigDescriber { | ||
return &DeploymentConfigDescriber{ | ||
client: &genericDeploymentDescriberClient{ | ||
getDeploymentConfig: func(namespace, name string) (*deployapi.DeploymentConfig, error) { | ||
return client.DeploymentConfigs(namespace).Get(name) | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func (d *DeploymentConfigDescriber) Describe(namespace, name string) (string, error) { | ||
deploymentConfig, err := d.client.GetDeploymentConfig(namespace, name) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return tabbedString(func(out *tabwriter.Writer) error { | ||
formatMeta(out, deploymentConfig.ObjectMeta) | ||
|
||
if deploymentConfig.LatestVersion == 0 { | ||
formatString(out, "Latest Version", "Not deployed") | ||
} else { | ||
formatString(out, "Latest Version", strconv.Itoa(deploymentConfig.LatestVersion)) | ||
} | ||
|
||
printStrategy(deploymentConfig.Template.Strategy, out) | ||
printTriggers(deploymentConfig.Triggers, out) | ||
printReplicationController(deploymentConfig.Template.ControllerTemplate, out) | ||
|
||
return nil | ||
}) | ||
} | ||
|
||
func printStrategy(strategy deployapi.DeploymentStrategy, w io.Writer) { | ||
fmt.Fprintf(w, "Strategy:\t%s\n", strategy.Type) | ||
switch strategy.Type { | ||
case deployapi.DeploymentStrategyTypeRecreate: | ||
case deployapi.DeploymentStrategyTypeCustom: | ||
fmt.Fprintf(w, "\t- Image:\t%s\n", strategy.CustomParams.Image) | ||
|
||
if len(strategy.CustomParams.Environment) > 0 { | ||
fmt.Fprintf(w, "\t- Environment:\t%s\n", formatLabels(convertEnv(strategy.CustomParams.Environment))) | ||
} | ||
|
||
if len(strategy.CustomParams.Command) > 0 { | ||
fmt.Fprintf(w, "\t- Command:\t%v\n", strings.Join(strategy.CustomParams.Command, " ")) | ||
} | ||
} | ||
} | ||
|
||
func printTriggers(triggers []deployapi.DeploymentTriggerPolicy, w io.Writer) { | ||
if len(triggers) == 0 { | ||
fmt.Fprint(w, "No triggers.") | ||
return | ||
} | ||
|
||
fmt.Fprint(w, "Triggers:\n") | ||
for _, t := range triggers { | ||
fmt.Fprintf(w, "\t- %s\n", t.Type) | ||
switch t.Type { | ||
case deployapi.DeploymentTriggerOnConfigChange: | ||
fmt.Fprintf(w, "\t\t<no options>\n") | ||
case deployapi.DeploymentTriggerOnImageChange: | ||
fmt.Fprintf(w, "\t\tAutomatic:\t%v\n\t\tRepository:\t%s\n\t\tTag:\t%s\n", | ||
t.ImageChangeParams.Automatic, | ||
t.ImageChangeParams.RepositoryName, | ||
t.ImageChangeParams.Tag, | ||
) | ||
default: | ||
fmt.Fprint(w, "unknown\n") | ||
} | ||
} | ||
} | ||
|
||
func printReplicationController(spec kapi.ReplicationControllerSpec, w io.Writer) error { | ||
fmt.Fprint(w, "Template:\n") | ||
|
||
fmt.Fprintf(w, "\tSelector:\t%s\n\tReplicas:\t%d\n", | ||
formatLabels(spec.Selector), | ||
spec.Replicas) | ||
|
||
fmt.Fprintf(w, "\tContainers:\n\t\tNAME\tIMAGE\tENV\n") | ||
for _, container := range spec.Template.Spec.Containers { | ||
fmt.Fprintf(w, "\t\t%s\t%s\t%s\n", | ||
container.Name, | ||
container.Image, | ||
formatLabels(convertEnv(container.Env))) | ||
} | ||
return nil | ||
} | ||
|
||
// DeploymentDescriber generates information about a deployment | ||
// DEPRECATED. | ||
type DeploymentDescriber struct { | ||
client.Interface | ||
} | ||
|
||
func (d *DeploymentDescriber) Describe(namespace, name string) (string, error) { | ||
c := d.Deployments(namespace) | ||
deployment, err := c.Get(name) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return tabbedString(func(out *tabwriter.Writer) error { | ||
formatMeta(out, deployment.ObjectMeta) | ||
formatString(out, "Status", bold(deployment.Status)) | ||
formatString(out, "Strategy", deployment.Strategy.Type) | ||
causes := []string{} | ||
if deployment.Details != nil { | ||
for _, c := range deployment.Details.Causes { | ||
causes = append(causes, string(c.Type)) | ||
} | ||
} | ||
formatString(out, "Causes", strings.Join(causes, ",")) | ||
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
Oops, something went wrong.