Merge pull request #26761 from matchstick/dedent

Automatic merge from submit-queue

Dedent

Adding the dedent package and then applying it to the kubectl help commands. Also updating the documentation to reflect the use of dedent.
This commit is contained in:
k8s-merge-robot 2016-06-28 12:50:59 -07:00 committed by GitHub
commit 13bb931b60
51 changed files with 860 additions and 555 deletions

5
Godeps/Godeps.json generated
View File

@ -1773,6 +1773,11 @@
"Comment": "v1.0.0-920-g934dbf8", "Comment": "v1.0.0-920-g934dbf8",
"Rev": "934dbf81977c67c521c75492dc1f55ca74dc5b04" "Rev": "934dbf81977c67c521c75492dc1f55ca74dc5b04"
}, },
{
"ImportPath": "github.com/renstrom/dedent",
"Comment": "v1.0.0-3-g020d11c",
"Rev": "020d11c3b9c0c7a3c2efcc8e5cf5b9ef7bcea21f"
},
{ {
"ImportPath": "github.com/robfig/cron", "ImportPath": "github.com/robfig/cron",
"Comment": "v1-16-g0f39cf7", "Comment": "v1-16-g0f39cf7",

29
Godeps/LICENSES generated
View File

@ -57322,6 +57322,35 @@ specific language governing permissions and limitations under the License.
================================================================================ ================================================================================
================================================================================
= vendor/github.com/renstrom/dedent licensed under: =
The MIT License (MIT)
Copyright (c) 2015 Peter Renström
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
= vendor/github.com/renstrom/dedent/LICENSE 285693e07a6e1fd790cb3f3b8b5127db -
================================================================================
================================================================================ ================================================================================
= vendor/github.com/robfig/cron licensed under: = = vendor/github.com/robfig/cron licensed under: =

View File

@ -279,15 +279,17 @@ type MineConfig struct {
mineLatest bool mineLatest bool
} }
const ( var (
mineLong = `Some long description mineLong = dedent.Dedent(`
for my command.` mine which is described here
with lots of details.`)
mineExample = ` # Run my command's first action mineExample = dedent.Dedent(`
$ %[1]s first # Run my command's first action
kubectl mine first_action
# Run my command's second action on latest stuff # Run my command's second action on latest stuff
$ %[1]s second --latest` kubectl mine second_action --flag`)
) )
// NewCmdMine implements the kubectl mine command. // NewCmdMine implements the kubectl mine command.

View File

@ -25,6 +25,7 @@ import (
"strings" "strings"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -58,42 +59,43 @@ type AnnotateOptions struct {
recursive bool recursive bool
} }
const ( var (
annotate_resources = ` annotate_resources = `
pod (po), service (svc), replicationcontroller (rc), pod (po), service (svc), replicationcontroller (rc),
node (no), event (ev), componentstatuse (cs), node (no), event (ev), componentstatuse (cs),
limitrange (limits), persistentvolume (pv), persistentvolumeclaim (pvc), limitrange (limits), persistentvolume (pv), persistentvolumeclaim (pvc),
horizontalpodautoscaler (hpa), resourcequota (quota), secret horizontalpodautoscaler (hpa), resourcequota (quota), secret`
`
annotate_long = `Update the annotations on one or more resources. annotate_long = dedent.Dedent(`
Update the annotations on one or more resources.
An annotation is a key/value pair that can hold larger (compared to a label), and possibly not human-readable, data. An annotation is a key/value pair that can hold larger (compared to a label), and possibly not human-readable, data.
It is intended to store non-identifying auxiliary data, especially data manipulated by tools and system extensions. It is intended to store non-identifying auxiliary data, especially data manipulated by tools and system extensions.
If --overwrite is true, then existing annotations can be overwritten, otherwise attempting to overwrite an annotation will result in an error. If --overwrite is true, then existing annotations can be overwritten, otherwise attempting to overwrite an annotation will result in an error.
If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used. If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.
Possible resources include (case insensitive):` + annotate_resources Possible resources include (case insensitive):`) + annotate_resources
annotate_example = `# Update pod 'foo' with the annotation 'description' and the value 'my frontend'. annotate_example = dedent.Dedent(`
# If the same annotation is set multiple times, only the last value will be applied # Update pod 'foo' with the annotation 'description' and the value 'my frontend'.
kubectl annotate pods foo description='my frontend' # If the same annotation is set multiple times, only the last value will be applied
kubectl annotate pods foo description='my frontend'
# Update a pod identified by type and name in "pod.json" # Update a pod identified by type and name in "pod.json"
kubectl annotate -f pod.json description='my frontend' kubectl annotate -f pod.json description='my frontend'
# Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value. # Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value.
kubectl annotate --overwrite pods foo description='my frontend running nginx' kubectl annotate --overwrite pods foo description='my frontend running nginx'
# Update all pods in the namespace # Update all pods in the namespace
kubectl annotate pods --all description='my frontend running nginx' kubectl annotate pods --all description='my frontend running nginx'
# Update pod 'foo' only if the resource is unchanged from version 1. # Update pod 'foo' only if the resource is unchanged from version 1.
kubectl annotate pods foo description='my frontend running nginx' --resource-version=1 kubectl annotate pods foo description='my frontend running nginx' --resource-version=1
# Update pod 'foo' by removing an annotation named 'description' if it exists. # Update pod 'foo' by removing an annotation named 'description' if it exists.
# Does not require the --overwrite flag. # Does not require the --overwrite flag.
kubectl annotate pods foo description-` kubectl annotate pods foo description-`)
) )
func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -22,6 +22,7 @@ import (
"time" "time"
"github.com/jonboulle/clockwork" "github.com/jonboulle/clockwork"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@ -50,17 +51,20 @@ const (
triesBeforeBackOff = 1 triesBeforeBackOff = 1
) )
const ( var (
apply_long = `Apply a configuration to a resource by filename or stdin. apply_long = dedent.Dedent(`
The resource will be created if it doesn't exist yet. Apply a configuration to a resource by filename or stdin.
To use 'apply', always create the resource initially with either 'apply' or 'create --save-config'. This resource will be created if it doesn't exist yet.
To use 'apply', always create the resource initially with either 'apply' or 'create --save-config'.
JSON and YAML formats are accepted.` JSON and YAML formats are accepted.`)
apply_example = `# Apply the configuration in pod.json to a pod.
kubectl apply -f ./pod.json
# Apply the JSON passed into stdin to a pod. apply_example = dedent.Dedent(`
cat pod.json | kubectl apply -f -` # Apply the configuration in pod.json to a pod.
kubectl apply -f ./pod.json
# Apply the JSON passed into stdin to a pod.
cat pod.json | kubectl apply -f -`)
) )
func NewCmdApply(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdApply(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -22,6 +22,7 @@ import (
"net/url" "net/url"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@ -35,16 +36,17 @@ import (
"k8s.io/kubernetes/pkg/util/term" "k8s.io/kubernetes/pkg/util/term"
) )
const ( var (
attach_example = `# Get output from running pod 123456-7890, using the first container by default attach_example = dedent.Dedent(`
kubectl attach 123456-7890 # Get output from running pod 123456-7890, using the first container by default
kubectl attach 123456-7890
# Get output from ruby-container from pod 123456-7890 # Get output from ruby-container from pod 123456-7890
kubectl attach 123456-7890 -c ruby-container kubectl attach 123456-7890 -c ruby-container
# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890 # Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890
# and sends stdout/stderr from 'bash' back to the client # and sends stdout/stderr from 'bash' back to the client
kubectl attach 123456-7890 -c ruby-container -i -t` kubectl attach 123456-7890 -c ruby-container -i -t`)
) )
func NewCmdAttach(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command { func NewCmdAttach(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {

View File

@ -20,6 +20,8 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
@ -35,17 +37,19 @@ type AutoscaleOptions struct {
Recursive bool Recursive bool
} }
const ( var (
autoscaleLong = `Creates an autoscaler that automatically chooses and sets the number of pods that run in a kubernetes cluster. autoscaleLong = dedent.Dedent(`
Creates an autoscaler that automatically chooses and sets the number of pods that run in a kubernetes cluster.
Looks up a Deployment, ReplicaSet, or ReplicationController by name and creates an autoscaler that uses the given resource as a reference. Looks up a Deployment, ReplicaSet, or ReplicationController by name and creates an autoscaler that uses the given resource as a reference.
An autoscaler can automatically increase or decrease number of pods deployed within the system as needed.` An autoscaler can automatically increase or decrease number of pods deployed within the system as needed.`)
autoscaleExample = `# Auto scale a deployment "foo", with the number of pods between 2 to 10, no target CPU utilization specfied so a default autoscaling policy will be used: autoscaleExample = dedent.Dedent(`
kubectl autoscale deployment foo --min=2 --max=10 # Auto scale a deployment "foo", with the number of pods between 2 to 10, target CPU utilization specified so a default autoscaling policy will be used:
kubectl autoscale deployment foo --min=2 --max=10
# Auto scale a replication controller "foo", with the number of pods between 1 to 5, target CPU utilization at 80%: # Auto scale a replication controller "foo", with the number of pods between 1 to 5, target CPU utilization at 80%:
kubectl autoscale rc foo --max=5 --cpu-percent=80` kubectl autoscale rc foo --max=5 --cpu-percent=80`)
) )
func NewCmdAutoscale(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdAutoscale(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -24,6 +24,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -44,7 +45,9 @@ type createAuthInfoOptions struct {
embedCertData flag.Tristate embedCertData flag.Tristate
} }
var create_authinfo_long = fmt.Sprintf(`Sets a user entry in kubeconfig var (
create_authinfo_long = fmt.Sprintf(`
Sets a user entry in kubeconfig
Specifying a name that already exists will merge new fields on top of existing values. Specifying a name that already exists will merge new fields on top of existing values.
Client-certificate flags: Client-certificate flags:
@ -59,15 +62,17 @@ Specifying a name that already exists will merge new fields on top of existing v
Bearer token and basic auth are mutually exclusive. Bearer token and basic auth are mutually exclusive.
`, clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword) `, clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword)
const create_authinfo_example = `# Set only the "client-key" field on the "cluster-admin" create_authinfo_example = dedent.Dedent(`
# entry, without touching other values: # Set only the "client-key" field on the "cluster-admin"
kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key # entry, without touching other values:
kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key
# Set basic auth for the "cluster-admin" entry # Set basic auth for the "cluster-admin" entry
kubectl config set-credentials cluster-admin --username=admin --password=uXFGweU9l35qcif kubectl config set-credentials cluster-admin --username=admin --password=uXFGweU9l35qcif
# Embed client certificate data in the "cluster-admin" entry # Embed client certificate data in the "cluster-admin" entry
kubectl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true` kubectl config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true`)
)
func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &createAuthInfoOptions{configAccess: configAccess} options := &createAuthInfoOptions{configAccess: configAccess}

View File

@ -23,6 +23,7 @@ import (
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -41,17 +42,19 @@ type createClusterOptions struct {
embedCAData flag.Tristate embedCAData flag.Tristate
} }
const ( var (
create_cluster_long = `Sets a cluster entry in kubeconfig. create_cluster_long = dedent.Dedent(`
Specifying a name that already exists will merge new fields on top of existing values for those fields.` Sets a cluster entry in kubeconfig.
create_cluster_example = `# Set only the server field on the e2e cluster entry without touching other values. Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
kubectl config set-cluster e2e --server=https://1.2.3.4 create_cluster_example = dedent.Dedent(`
# Set only the server field on the e2e cluster entry without touching other values.
kubectl config set-cluster e2e --server=https://1.2.3.4
# Embed certificate authority data for the e2e cluster entry # Embed certificate authority data for the e2e cluster entry
kubectl config set-cluster e2e --certificate-authority=~/.kube/e2e/kubernetes.ca.crt kubectl config set-cluster e2e --certificate-authority=~/.kube/e2e/kubernetes.ca.crt
# Disable cert checking for the dev cluster entry # Disable cert checking for the dev cluster entry
kubectl config set-cluster e2e --insecure-skip-tls-verify=true` kubectl config set-cluster e2e --insecure-skip-tls-verify=true`)
) )
func NewCmdConfigSetCluster(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSetCluster(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {

View File

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -36,11 +37,13 @@ type createContextOptions struct {
namespace util.StringFlag namespace util.StringFlag
} }
const ( var (
create_context_long = `Sets a context entry in kubeconfig create_context_long = dedent.Dedent(`
Specifying a name that already exists will merge new fields on top of existing values for those fields.` Sets a context entry in kubeconfig
create_context_example = `# Set the user field on the gce context entry without touching other values Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
kubectl config set-context gce --user=cluster-admin` create_context_example = dedent.Dedent(`
# Set the user field on the gce context entry without touching other values
kubectl config set-context gce --user=cluster-admin`)
) )
func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -30,10 +31,12 @@ type CurrentContextOptions struct {
ConfigAccess clientcmd.ConfigAccess ConfigAccess clientcmd.ConfigAccess
} }
const ( var (
current_context_long = `Displays the current-context` current_context_long = dedent.Dedent(`
current_context_example = `# Display the current-context Displays the current-context`)
kubectl config current-context` current_context_example = dedent.Dedent(`
# Display the current-context
kubectl config current-context`)
) )
func NewCmdConfigCurrentContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigCurrentContext(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {

View File

@ -24,6 +24,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -42,9 +43,10 @@ type setOptions struct {
setRawBytes flag.Tristate setRawBytes flag.Tristate
} }
const set_long = `Sets an individual value in a kubeconfig file var set_long = dedent.Dedent(`
PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots. Sets an individual value in a kubeconfig file
PROPERTY_VALUE is the new value you wish to set. Binary fields such as 'certificate-authority-data' expect a base64 encoded string unless the --set-raw-bytes flag is used.` PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.
PROPERTY_VALUE is the new value you wish to set. Binary fields such as 'certificate-authority-data' expect a base64 encoded string unless the --set-raw-bytes flag is used.`)
func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &setOptions{configAccess: configAccess} options := &setOptions{configAccess: configAccess}

View File

@ -22,6 +22,7 @@ import (
"io" "io"
"reflect" "reflect"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -32,8 +33,9 @@ type unsetOptions struct {
propertyName string propertyName string
} }
const unset_long = `Unsets an individual value in a kubeconfig file var unset_long = dedent.Dedent(`
PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.` Unsets an individual value in a kubeconfig file
PROPERTY_NAME is a dot delimited name where each token represents either a attribute name or a map key. Map keys may not contain dots.`)
func NewCmdConfigUnset(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigUnset(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
options := &unsetOptions{configAccess: configAccess} options := &unsetOptions{configAccess: configAccess}

View File

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
@ -39,15 +40,17 @@ type ViewOptions struct {
RawByteData bool RawByteData bool
} }
const ( var (
view_long = `Displays merged kubeconfig settings or a specified kubeconfig file. view_long = dedent.Dedent(`
Displays merged kubeconfig settings or a specified kubeconfig file.
You can use --output jsonpath={...} to extract specific values using a jsonpath expression.` You can use --output jsonpath={...} to extract specific values using a jsonpath expression.`)
view_example = `# Show Merged kubeconfig settings. view_example = dedent.Dedent(`
kubectl config view # Show Merged kubeconfig settings.
kubectl config view
# Get the password for the e2e user # Get the password for the e2e user
kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'` kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'`)
) )
func NewCmdConfigView(out io.Writer, ConfigAccess clientcmd.ConfigAccess) *cobra.Command { func NewCmdConfigView(out io.Writer, ConfigAccess clientcmd.ConfigAccess) *cobra.Command {

View File

@ -20,6 +20,8 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
@ -31,27 +33,30 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const ( var (
convert_long = `Convert config files between different API versions. Both YAML convert_long = dedent.Dedent(`
and JSON formats are accepted. Convert config files between different API versions. Both YAML
and JSON formats are accepted.
The command takes filename, directory, or URL as input, and convert it into format The command takes filename, directory, or URL as input, and convert it into format
of version specified by --output-version flag. If target version is not specified or of version specified by --output-version flag. If target version is not specified or
not supported, convert to latest version. not supported, convert to latest version.
The default output will be printed to stdout in YAML format. One can use -o option The default output will be printed to stdout in YAML format. One can use -o option
to change to output destination. to change to output destination.
` `)
convert_example = `# Convert 'pod.yaml' to latest version and print to stdout.
kubectl convert -f pod.yaml
# Convert the live state of the resource specified by 'pod.yaml' to the latest version convert_example = dedent.Dedent(`
# and print to stdout in json format. # Convert 'pod.yaml' to latest version and print to stdout.
kubectl convert -f pod.yaml --local -o json kubectl convert -f pod.yaml
# Convert all files under current directory to latest version and create them all. # Convert the live state of the resource specified by 'pod.yaml' to the latest version
kubectl convert -f . | kubectl create -f - # and print to stdout in json format.
` kubectl convert -f pod.yaml --local -o json
# Convert all files under current directory to latest version and create them all.
kubectl convert -f . | kubectl create -f -
`)
) )
// NewCmdConvert creates a command object for the generic "convert" action, which // NewCmdConvert creates a command object for the generic "convert" action, which

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
@ -35,15 +36,17 @@ type CreateOptions struct {
Recursive bool Recursive bool
} }
const ( var (
create_long = `Create a resource by filename or stdin. create_long = dedent.Dedent(`
Create a resource by filename or stdin.
JSON and YAML formats are accepted.` JSON and YAML formats are accepted.`)
create_example = `# Create a pod using the data in pod.json. create_example = dedent.Dedent(`
kubectl create -f ./pod.json # Create a pod using the data in pod.json.
kubectl create -f ./pod.json
# Create a pod based on the JSON passed into stdin. # Create a pod based on the JSON passed into stdin.
cat pod.json | kubectl create -f -` cat pod.json | kubectl create -f -`)
) )
func NewCmdCreate(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdCreate(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -20,33 +20,36 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
configMapLong = `Create a configmap based on a file, directory, or specified literal value. configMapLong = dedent.Dedent(`
Create a configmap based on a file, directory, or specified literal value.
A single configmap may package one or more key/value pairs. A single configmap may package one or more key/value pairs.
When creating a configmap based on a file, the key will default to the basename of the file, and the value will When creating a configmap based on a file, the key will default to the basename of the file, and the value will
default to the file content. If the basename is an invalid key, you may specify an alternate key. default to the file content. If the basename is an invalid key, you may specify an alternate key.
When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be
packaged into the configmap. Any directory entries except regular files are ignored (e.g. subdirectories, packaged into the configmap. Any directory entries except regular files are ignored (e.g. subdirectories,
symlinks, devices, pipes, etc). symlinks, devices, pipes, etc).
` `)
configMapExample = ` # Create a new configmap named my-config with keys for each file in folder bar configMapExample = dedent.Dedent(`
kubectl create configmap my-config --from-file=path/to/bar # Create a new configmap named my-config with keys for each file in folder bar
kubectl create configmap my-config --from-file=path/to/bar
# Create a new configmap named my-config with specified keys instead of names on disk # Create a new configmap named my-config with specified keys instead of names on disk
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
# Create a new configMap named my-config with key1=config1 and key2=config2 # Create a new configMap named my-config with key1=config1 and key2=config2
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2` kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2`)
) )
// ConfigMap is a command to ease creating ConfigMaps. // ConfigMap is a command to ease creating ConfigMaps.

View File

@ -20,18 +20,20 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
namespaceLong = ` namespaceLong = dedent.Dedent(`
Create a namespace with the specified name.` Create a namespace with the specified name.`)
namespaceExample = ` # Create a new namespace named my-namespace namespaceExample = dedent.Dedent(`
kubectl create namespace my-namespace` # Create a new namespace named my-namespace
kubectl create namespace my-namespace`)
) )
// NewCmdCreateNamespace is a macro command to create a new namespace // NewCmdCreateNamespace is a macro command to create a new namespace

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
@ -43,28 +44,29 @@ func NewCmdCreateSecret(f *cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
return cmd return cmd
} }
const ( var (
secretLong = ` secretLong = dedent.Dedent(`
Create a secret based on a file, directory, or specified literal value. Create a secret based on a file, directory, or specified literal value.
A single secret may package one or more key/value pairs. A single secret may package one or more key/value pairs.
When creating a secret based on a file, the key will default to the basename of the file, and the value will When creating a secret based on a file, the key will default to the basename of the file, and the value will
default to the file content. If the basename is an invalid key, you may specify an alternate key. default to the file content. If the basename is an invalid key, you may specify an alternate key.
When creating a secret based on a directory, each file whose basename is a valid key in the directory will be When creating a secret based on a directory, each file whose basename is a valid key in the directory will be
packaged into the secret. Any directory entries except regular files are ignored (e.g. subdirectories, packaged into the secret. Any directory entries except regular files are ignored (e.g. subdirectories,
symlinks, devices, pipes, etc). symlinks, devices, pipes, etc).
` `)
secretExample = ` # Create a new secret named my-secret with keys for each file in folder bar secretExample = dedent.Dedent(`
kubectl create secret generic my-secret --from-file=path/to/bar # Create a new secret named my-secret with keys for each file in folder bar
kubectl create secret generic my-secret --from-file=path/to/bar
# Create a new secret named my-secret with specified keys instead of names on disk # Create a new secret named my-secret with specified keys instead of names on disk
kubectl create secret generic my-secret --from-file=ssh-privatekey=~/.ssh/id_rsa --from-file=ssh-publickey=~/.ssh/id_rsa.pub kubectl create secret generic my-secret --from-file=ssh-privatekey=~/.ssh/id_rsa --from-file=ssh-publickey=~/.ssh/id_rsa.pub
# Create a new secret named my-secret with key1=supersecret and key2=topsecret # Create a new secret named my-secret with key1=supersecret and key2=topsecret
kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret` kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret`)
) )
// NewCmdCreateSecretGeneric is a command to create generic secrets from files, directories, or literal values // NewCmdCreateSecretGeneric is a command to create generic secrets from files, directories, or literal values
@ -115,23 +117,24 @@ func CreateSecretGeneric(f *cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Comman
}) })
} }
const ( var (
secretForDockerRegistryLong = ` secretForDockerRegistryLong = dedent.Dedent(`
Create a new secret for use with Docker registries. Create a new secret for use with Docker registries.
Dockercfg secrets are used to authenticate against Docker registries. Dockercfg secrets are used to authenticate against Docker registries.
When using the Docker command line to push images, you can authenticate to a given registry by running When using the Docker command line to push images, you can authenticate to a given registry by running
'docker login DOCKER_REGISTRY_SERVER --username=DOCKER_USER --password=DOCKER_PASSWORD --email=DOCKER_EMAIL'. 'docker login DOCKER_REGISTRY_SERVER --username=DOCKER_USER --password=DOCKER_PASSWORD --email=DOCKER_EMAIL'.
That produces a ~/.dockercfg file that is used by subsequent 'docker push' and 'docker pull' commands to That produces a ~/.dockercfg file that is used by subsequent 'docker push' and 'docker pull' commands to
authenticate to the registry. authenticate to the registry.
When creating applications, you may have a Docker registry that requires authentication. In order for the When creating applications, you may have a Docker registry that requires authentication. In order for the
nodes to pull images on your behalf, they have to have the credentials. You can provide this information nodes to pull images on your behalf, they have to have the credentials. You can provide this information
by creating a dockercfg secret and attaching it to your service account.` by creating a dockercfg secret and attaching it to your service account.`)
secretForDockerRegistryExample = ` # If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using: secretForDockerRegistryExample = dedent.Dedent(`
kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL` # If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL`)
) )
// NewCmdCreateSecretDockerRegistry is a macro command for creating secrets to work with Docker registries // NewCmdCreateSecretDockerRegistry is a macro command for creating secrets to work with Docker registries
@ -194,14 +197,15 @@ func CreateSecretDockerRegistry(f *cmdutil.Factory, cmdOut io.Writer, cmd *cobra
}) })
} }
const ( var (
secretForTLSLong = ` secretForTLSLong = dedent.Dedent(`
Create a TLS secret from the given public/private key pair. Create a TLS secret from the given public/private key pair.
The public/private key pair must exist before hand. The public key certificate must be .PEM encoded and match the given private key.` The public/private key pair must exist before hand. The public key certificate must be .PEM encoded and match the given private key.`)
secretForTLSExample = ` # Create a new TLS secret named tls-secret with the given key pair: secretForTLSExample = dedent.Dedent(`
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key` # Create a new TLS secret named tls-secret with the given key pair:
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key`)
) )
// NewCmdCreateSecretTLS is a macro command for creating secrets to work with Docker registries // NewCmdCreateSecretTLS is a macro command for creating secrets to work with Docker registries

View File

@ -20,18 +20,20 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
serviceAccountLong = ` serviceAccountLong = dedent.Dedent(`
Create a service account with the specified name.` Create a service account with the specified name.`)
serviceAccountExample = ` # Create a new service account named my-service-account serviceAccountExample = dedent.Dedent(`
$ kubectl create serviceaccount my-service-account` # Create a new service account named my-service-account
$ kubectl create serviceaccount my-service-account`)
) )
// NewCmdCreateServiceAccount is a macro command to create a new service account // NewCmdCreateServiceAccount is a macro command to create a new service account

View File

@ -21,6 +21,7 @@ import (
"io" "io"
"time" "time"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@ -38,36 +39,38 @@ type DeleteOptions struct {
Recursive bool Recursive bool
} }
const ( var (
delete_long = `Delete resources by filenames, stdin, resources and names, or by resources and label selector. delete_long = dedent.Dedent(`
Delete resources by filenames, stdin, resources and names, or by resources and label selector.
JSON and YAML formats are accepted. JSON and YAML formats are accepted.
Only one type of the arguments may be specified: filenames, resources and names, or resources and label selector Only one type of the arguments may be specified: filenames, resources and names, or resources and label selector
Note that the delete command does NOT do resource version checks, so if someone Note that the delete command does NOT do resource version checks, so if someone
submits an update to a resource right when you submit a delete, their update submits an update to a resource right when you submit a delete, their update
will be lost along with the rest of the resource.` will be lost along with the rest of the resource.`)
delete_example = `# Delete a pod using the type and name specified in pod.json. delete_example = dedent.Dedent(`
kubectl delete -f ./pod.json # Delete a pod using the type and name specified in pod.json.
kubectl delete -f ./pod.json
# Delete a pod based on the type and name in the JSON passed into stdin. # Delete a pod based on the type and name in the JSON passed into stdin.
cat pod.json | kubectl delete -f - cat pod.json | kubectl delete -f -
# Delete pods and services with same names "baz" and "foo" # Delete pods and services with same names "baz" and "foo"
kubectl delete pod,service baz foo kubectl delete pod,service baz foo
# Delete pods and services with label name=myLabel. # Delete pods and services with label name=myLabel.
kubectl delete pods,services -l name=myLabel kubectl delete pods,services -l name=myLabel
# Delete a pod immediately (no graceful shutdown) # Delete a pod immediately (no graceful shutdown)
kubectl delete pod foo --now kubectl delete pod foo --now
# Delete a pod with UID 1234-56-7890-234234-456456. # Delete a pod with UID 1234-56-7890-234234-456456.
kubectl delete pod 1234-56-7890-234234-456456 kubectl delete pod 1234-56-7890-234234-456456
# Delete all pods # Delete all pods
kubectl delete pods --all` kubectl delete pods --all`)
) )
func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -21,6 +21,7 @@ import (
"io" "io"
"strings" "strings"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
apierrors "k8s.io/kubernetes/pkg/api/errors" apierrors "k8s.io/kubernetes/pkg/api/errors"
@ -39,36 +40,39 @@ type DescribeOptions struct {
Recursive bool Recursive bool
} }
const ( var (
describe_long = `Show details of a specific resource or group of resources. describe_long = dedent.Dedent(`
Show details of a specific resource or group of resources.
This command joins many API calls together to form a detailed description of a
given resource or group of resources.
This command joins many API calls together to form a detailed description of a $ kubectl describe TYPE NAME_PREFIX
given resource or group of resources.
$ kubectl describe TYPE NAME_PREFIX will first check for an exact match on TYPE and NAME_PREFIX. If no such resource
exists, it will output details for every resource that has a name prefixed with NAME_PREFIX.
will first check for an exact match on TYPE and NAME_PREFIX. If no such resource `) +
exists, it will output details for every resource that has a name prefixed with NAME_PREFIX kubectl.PossibleResourceTypes
` + kubectl.PossibleResourceTypes describe_example = dedent.Dedent(`
describe_example = `# Describe a node # Describe a node
kubectl describe nodes kubernetes-minion-emt8.c.myproject.internal kubectl describe nodes kubernetes-minion-emt8.c.myproject.internal
# Describe a pod # Describe a pod
kubectl describe pods/nginx kubectl describe pods/nginx
# Describe a pod identified by type and name in "pod.json" # Describe a pod identified by type and name in "pod.json"
kubectl describe -f pod.json kubectl describe -f pod.json
# Describe all pods # Describe all pods
kubectl describe pods kubectl describe pods
# Describe pods by label name=myLabel # Describe pods by label name=myLabel
kubectl describe po -l name=myLabel kubectl describe po -l name=myLabel
# Describe all pods managed by the 'frontend' replication controller (rc-created pods # Describe all pods managed by the 'frontend' replication controller (rc-created pods
# get the name of the rc as a prefix in the pod the name). # get the name of the rc as a prefix in the pod the name).
kubectl describe pods frontend` kubectl describe pods frontend`)
) )
func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdDescribe(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -23,6 +23,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@ -66,11 +67,16 @@ const (
kLocalStorageWarning = "Deleting pods with local storage" kLocalStorageWarning = "Deleting pods with local storage"
kUnmanagedFatal = "pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet (use --force to override)" kUnmanagedFatal = "pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet (use --force to override)"
kUnmanagedWarning = "Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet" kUnmanagedWarning = "Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet"
cordon_long = `Mark node as unschedulable. )
`
cordon_example = `# Mark node "foo" as unschedulable. var (
kubectl cordon foo cordon_long = dedent.Dedent(`
` Mark node as unschedulable.
`)
cordon_example = dedent.Dedent(`
# Mark node "foo" as unschedulable.
kubectl cordon foo
`)
) )
func NewCmdCordon(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdCordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
@ -89,12 +95,14 @@ func NewCmdCordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
return cmd return cmd
} }
const ( var (
uncordon_long = `Mark node as schedulable. uncordon_long = dedent.Dedent(`
` Mark node as schedulable.
uncordon_example = `# Mark node "foo" as schedulable. `)
$ kubectl uncordon foo uncordon_example = dedent.Dedent(`
` # Mark node "foo" as schedulable.
$ kubectl uncordon foo
`)
) )
func NewCmdUncordon(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdUncordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
@ -113,28 +121,31 @@ func NewCmdUncordon(f *cmdutil.Factory, out io.Writer) *cobra.Command {
return cmd return cmd
} }
const ( var (
drain_long = `Drain node in preparation for maintenance. drain_long = dedent.Dedent(`
Drain node in preparation for maintenance.
The given node will be marked unschedulable to prevent new pods from arriving. The given node will be marked unschedulable to prevent new pods from arriving.
Then drain deletes all pods except mirror pods (which cannot be deleted through Then drain deletes all pods except mirror pods (which cannot be deleted through
the API server). If there are DaemonSet-managed pods, drain will not proceed the API server). If there are DaemonSet-managed pods, drain will not proceed
without --ignore-daemonsets, and regardless it will not delete any without --ignore-daemonsets, and regardless it will not delete any
DaemonSet-managed pods, because those pods would be immediately replaced by the DaemonSet-managed pods, because those pods would be immediately replaced by the
DaemonSet controller, which ignores unschedulable markings. If there are any DaemonSet controller, which ignores unschedulable markings. If there are any
pods that are neither mirror pods nor managed--by ReplicationController, pods that are neither mirror pods nor managed--by ReplicationController,
ReplicaSet, DaemonSet or Job--, then drain will not delete any pods unless you ReplicaSet, DaemonSet or Job--, then drain will not delete any pods unless you
use --force. use --force.
When you are ready to put the node back into service, use kubectl uncordon, which When you are ready to put the node back into service, use kubectl uncordon, which
will make the node schedulable again. will make the node schedulable again.
` `)
drain_example = `# Drain node "foo", even if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet on it.
$ kubectl drain foo --force
# As above, but abort if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet, and use a grace period of 15 minutes. drain_example = dedent.Dedent(`
$ kubectl drain foo --grace-period=900 # Drain node "foo", even if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet on it.
` $ kubectl drain foo --force
# As above, but abort if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet, and use a grace period of 15 minutes.
$ kubectl drain foo --grace-period=900
`)
) )
func NewCmdDrain(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdDrain(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -27,6 +27,7 @@ import (
gruntime "runtime" gruntime "runtime"
"strings" "strings"
"github.com/renstrom/dedent"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -45,35 +46,37 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const ( var (
editLong = `Edit a resource from the default editor. editLong = dedent.Dedent(`
Edit a resource from the default editor.
The edit command allows you to directly edit any API resource you can retrieve via the The edit command allows you to directly edit any API resource you can retrieve via the
command line tools. It will open the editor defined by your KUBE_EDITOR, or EDITOR command line tools. It will open the editor defined by your KUBE_EDITOR, or EDITOR
environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows. environment variables, or fall back to 'vi' for Linux or 'notepad' for Windows.
You can edit multiple objects, although changes are applied one at a time. The command You can edit multiple objects, although changes are applied one at a time. The command
accepts filenames as well as command line arguments, although the files you point to must accepts filenames as well as command line arguments, although the files you point to must
be previously saved versions of resources. be previously saved versions of resources.
The files to edit will be output in the default API version, or a version specified The files to edit will be output in the default API version, or a version specified
by --output-version. The default format is YAML - if you would like to edit in JSON by --output-version. The default format is YAML - if you would like to edit in JSON
pass -o json. The flag --windows-line-endings can be used to force Windows line endings, pass -o json. The flag --windows-line-endings can be used to force Windows line endings,
otherwise the default for your operating system will be used. otherwise the default for your operating system will be used.
In the event an error occurs while updating, a temporary file will be created on disk In the event an error occurs while updating, a temporary file will be created on disk
that contains your unapplied changes. The most common error when updating a resource that contains your unapplied changes. The most common error when updating a resource
is another editor changing the resource on the server. When this occurs, you will have is another editor changing the resource on the server. When this occurs, you will have
to apply your changes to the newer version of the resource, or update your temporary to apply your changes to the newer version of the resource, or update your temporary
saved copy to include the latest resource version.` saved copy to include the latest resource version.`)
editExample = ` # Edit the service named 'docker-registry': editExample = dedent.Dedent(`
kubectl edit svc/docker-registry # Edit the service named 'docker-registry':
kubectl edit svc/docker-registry
# Use an alternative editor # Use an alternative editor
KUBE_EDITOR="nano" kubectl edit svc/docker-registry KUBE_EDITOR="nano" kubectl edit svc/docker-registry
# Edit the service 'docker-registry' in JSON using the v1 API format: # Edit the service 'docker-registry' in JSON using the v1 API format:
kubectl edit svc/docker-registry --output-version=v1 -o json` kubectl edit svc/docker-registry --output-version=v1 -o json`)
) )
// EditOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of // EditOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of

View File

@ -26,6 +26,7 @@ import (
"github.com/docker/docker/pkg/term" "github.com/docker/docker/pkg/term"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
@ -35,16 +36,17 @@ import (
remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand" remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
) )
const ( var (
exec_example = `# Get output from running 'date' from pod 123456-7890, using the first container by default exec_example = dedent.Dedent(`
kubectl exec 123456-7890 date # Get output from running 'date' from pod 123456-7890, using the first container by default
kubectl exec 123456-7890 date
# Get output from running 'date' in ruby-container from pod 123456-7890 # Get output from running 'date' in ruby-container from pod 123456-7890
kubectl exec 123456-7890 -c ruby-container date kubectl exec 123456-7890 -c ruby-container date
# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890 # Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890
# and sends stdout/stderr from 'bash' back to the client # and sends stdout/stderr from 'bash' back to the client
kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il` kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il`)
) )
func NewCmdExec(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command { func NewCmdExec(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {

View File

@ -19,6 +19,7 @@ package cmd
import ( import (
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
@ -27,16 +28,18 @@ import (
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
explainExamples = `# Get the documentation of the resource and its fields explainExamples = dedent.Dedent(`
kubectl explain pods # Get the documentation of the resource and its fields
kubectl explain pods
# Get the documentation of a specific field of a resource # Get the documentation of a specific field of a resource
kubectl explain pods.spec.containers` kubectl explain pods.spec.containers`)
explainLong = `Documentation of resources. explainLong = dedent.Dedent(`
Documentation of resources.
` + kubectl.PossibleResourceTypes `) + kubectl.PossibleResourceTypes
) )
// NewCmdExplain returns a cobra command for swagger docs // NewCmdExplain returns a cobra command for swagger docs

View File

@ -22,6 +22,7 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
@ -38,43 +39,45 @@ type ExposeOptions struct {
Recursive bool Recursive bool
} }
const ( var (
expose_resources = ` expose_resources = dedent.Dedent(`
pod (po), service (svc), replicationcontroller (rc), pod (po), service (svc), replicationcontroller (rc),
deployment, replicaset (rs) deployment, replicaset (rs)
` `)
expose_long = `Expose a resource as a new Kubernetes service. expose_long = dedent.Dedent(`
Expose a resource as a new Kubernetes service.
Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector
for that resource as the selector for a new service on the specified port. A deployment or replica set for that resource as the selector for a new service on the specified port. A deployment or replica set
will be exposed as a service only if its selector is convertible to a selector that service supports, will be exposed as a service only if its selector is convertible to a selector that service supports,
i.e. when the selector contains only the matchLabels component. Note that if no port is specified via i.e. when the selector contains only the matchLabels component. Note that if no port is specified via
--port and the exposed resource has multiple ports, all will be re-used by the new service. Also if no --port and the exposed resource has multiple ports, all will be re-used by the new service. Also if no
labels are specified, the new service will re-use the labels from the resource it exposes. labels are specified, the new service will re-use the labels from the resource it exposes.
Possible resources include (case insensitive):` + expose_resources Possible resources include (case insensitive): `) + expose_resources
expose_example = `# Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000. expose_example = dedent.Dedent(`
kubectl expose rc nginx --port=80 --target-port=8000 # Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
kubectl expose rc nginx --port=80 --target-port=8000
# Create a service for a replication controller identified by type and name specified in "nginx-controller.yaml", which serves on port 80 and connects to the containers on port 8000. # Create a service for a replication controller identified by type and name specified in "nginx-controller.yaml", which serves on port 80 and connects to the containers on port 8000.
kubectl expose -f nginx-controller.yaml --port=80 --target-port=8000 kubectl expose -f nginx-controller.yaml --port=80 --target-port=8000
# Create a service for a pod valid-pod, which serves on port 444 with the name "frontend" # Create a service for a pod valid-pod, which serves on port 444 with the name "frontend"
kubectl expose pod valid-pod --port=444 --name=frontend kubectl expose pod valid-pod --port=444 --name=frontend
# Create a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx-https" # Create a second service based on the above service, exposing the container port 8443 as port 443 with the name "nginx-https"
kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https
# Create a service for a replicated streaming application on port 4100 balancing UDP traffic and named 'video-stream'. # Create a service for a replicated streaming application on port 4100 balancing UDP traffic and named 'video-stream'.
kubectl expose rc streamer --port=4100 --protocol=udp --name=video-stream kubectl expose rc streamer --port=4100 --protocol=udp --name=video-stream
# Create a service for a replicated nginx using replica set, which serves on port 80 and connects to the containers on port 8000. # Create a service for a replicated nginx using replica set, which serves on port 80 and connects to the containers on port 8000.
kubectl expose rs nginx --port=80 --target-port=8000 kubectl expose rs nginx --port=80 --target-port=8000
# Create a service for an nginx deployment, which serves on port 80 and connects to the containers on port 8000. # Create a service for an nginx deployment, which serves on port 80 and connects to the containers on port 8000.
kubectl expose deployment nginx --port=80 --target-port=8000` kubectl expose deployment nginx --port=80 --target-port=8000`)
) )
func NewCmdExposeService(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdExposeService(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
@ -37,36 +38,38 @@ type GetOptions struct {
Recursive bool Recursive bool
} }
const ( var (
get_long = `Display one or many resources. get_long = dedent.Dedent(`
Display one or many resources.
` + kubectl.PossibleResourceTypes + ` `) + kubectl.PossibleResourceTypes + dedent.Dedent(`
By specifying the output as 'template' and providing a Go template as the value By specifying the output as 'template' and providing a Go template as the value
of the --template flag, you can filter the attributes of the fetched resource(s).` of the --template flag, you can filter the attributes of the fetched resource(s).`)
get_example = `# List all pods in ps output format. get_example = dedent.Dedent(`
kubectl get pods # List all pods in ps output format.
kubectl get pods
# List all pods in ps output format with more information (such as node name). # List all pods in ps output format with more information (such as node name).
kubectl get pods -o wide kubectl get pods -o wide
# List a single replication controller with specified NAME in ps output format. # List a single replication controller with specified NAME in ps output format.
kubectl get replicationcontroller web kubectl get replicationcontroller web
# List a single pod in JSON output format. # List a single pod in JSON output format.
kubectl get -o json pod web-pod-13je7 kubectl get -o json pod web-pod-13je7
# List a pod identified by type and name specified in "pod.yaml" in JSON output format. # List a pod identified by type and name specified in "pod.yaml" in JSON output format.
kubectl get -f pod.yaml -o json kubectl get -f pod.yaml -o json
# Return only the phase value of the specified pod. # Return only the phase value of the specified pod.
kubectl get -o template pod/web-pod-13je7 --template={{.status.phase}} kubectl get -o template pod/web-pod-13je7 --template={{.status.phase}}
# List all replication controllers and services together in ps output format. # List all replication controllers and services together in ps output format.
kubectl get rc,services kubectl get rc,services
# List one or more resources by their type and names. # List one or more resources by their type and names.
kubectl get rc/web service/frontend pods/web-pod-13je7` kubectl get rc/web service/frontend pods/web-pod-13je7`)
) )
// NewCmdGet creates a command object for the generic "get" action, which // NewCmdGet creates a command object for the generic "get" action, which

View File

@ -24,6 +24,7 @@ import (
"strings" "strings"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -43,30 +44,32 @@ type LabelOptions struct {
Recursive bool Recursive bool
} }
const ( var (
label_long = `Update the labels on a resource. label_long = dedent.Dedent(`
Update the labels on a resource.
A label must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters. A label must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
If --overwrite is true, then existing labels can be overwritten, otherwise attempting to overwrite a label will result in an error. If --overwrite is true, then existing labels can be overwritten, otherwise attempting to overwrite a label will result in an error.
If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.` If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.`)
label_example = `# Update pod 'foo' with the label 'unhealthy' and the value 'true'. label_example = dedent.Dedent(`
kubectl label pods foo unhealthy=true # Update pod 'foo' with the label 'unhealthy' and the value 'true'.
kubectl label pods foo unhealthy=true
# Update pod 'foo' with the label 'status' and the value 'unhealthy', overwriting any existing value. # Update pod 'foo' with the label 'status' and the value 'unhealthy', overwriting any existing value.
kubectl label --overwrite pods foo status=unhealthy kubectl label --overwrite pods foo status=unhealthy
# Update all pods in the namespace # Update all pods in the namespace
kubectl label pods --all status=unhealthy kubectl label pods --all status=unhealthy
# Update a pod identified by the type and name in "pod.json" # Update a pod identified by the type and name in "pod.json"
kubectl label -f pod.json status=unhealthy kubectl label -f pod.json status=unhealthy
# Update pod 'foo' only if the resource is unchanged from version 1. # Update pod 'foo' only if the resource is unchanged from version 1.
kubectl label pods foo status=unhealthy --resource-version=1 kubectl label pods foo status=unhealthy --resource-version=1
# Update pod 'foo' by removing a label named 'bar' if it exists. # Update pod 'foo' by removing a label named 'bar' if it exists.
# Does not require the --overwrite flag. # Does not require the --overwrite flag.
kubectl label pods foo bar-` kubectl label pods foo bar-`)
) )
func NewCmdLabel(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdLabel(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -23,6 +23,7 @@ import (
"os" "os"
"time" "time"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -34,21 +35,22 @@ import (
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
const ( var (
logs_example = `# Return snapshot logs from pod nginx with only one container logs_example = dedent.Dedent(`
kubectl logs nginx # Return snapshot logs from pod nginx with only one container
kubectl logs nginx
# Return snapshot of previous terminated ruby container logs from pod web-1 # Return snapshot of previous terminated ruby container logs from pod web-1
kubectl logs -p -c ruby web-1 kubectl logs -p -c ruby web-1
# Begin streaming the logs of the ruby container in pod web-1 # Begin streaming the logs of the ruby container in pod web-1
kubectl logs -f -c ruby web-1 kubectl logs -f -c ruby web-1
# Display only the most recent 20 lines of output in pod nginx # Display only the most recent 20 lines of output in pod nginx
kubectl logs --tail=20 nginx kubectl logs --tail=20 nginx
# Show all logs from pod nginx written in the last hour # Show all logs from pod nginx written in the last hour
kubectl logs --since=1h nginx` kubectl logs --since=1h nginx`)
) )
type LogsOptions struct { type LogsOptions struct {

View File

@ -22,6 +22,7 @@ import (
"strings" "strings"
"github.com/evanphx/json-patch" "github.com/evanphx/json-patch"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@ -46,24 +47,26 @@ type PatchOptions struct {
OutputFormat string OutputFormat string
} }
const ( var (
patch_long = `Update field(s) of a resource using strategic merge patch patch_long = dedent.Dedent(`
Update field(s) of a resource using strategic merge patch
JSON and YAML formats are accepted. JSON and YAML formats are accepted.
Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.` Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.`)
patch_example = ` patch_example = dedent.Dedent(`
# Partially update a node using strategic merge patch
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
# Partially update a node identified by the type and name specified in "node.json" using strategic merge patch # Partially update a node using strategic merge patch
kubectl patch -f node.json -p '{"spec":{"unschedulable":true}}' kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
# Update a container's image; spec.containers[*].name is required because it's a merge key # Partially update a node identified by the type and name specified in "node.json" using strategic merge patch
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}' kubectl patch -f node.json -p '{"spec":{"unschedulable":true}}'
# Update a container's image using a json patch with positional arrays # Update a container's image; spec.containers[*].name is required because it's a merge key
kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'` kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'
# Update a container's image using a json patch with positional arrays
kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'`)
) )
func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -23,6 +23,7 @@ import (
"os/signal" "os/signal"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/restclient"
@ -31,19 +32,19 @@ import (
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
portforward_example = ` portforward_example = dedent.Dedent(`
# Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod # Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
kubectl port-forward mypod 5000 6000 kubectl port-forward mypod 5000 6000
# Listen on port 8888 locally, forwarding to 5000 in the pod # Listen on port 8888 locally, forwarding to 5000 in the pod
kubectl port-forward mypod 8888:5000 kubectl port-forward mypod 8888:5000
# Listen on a random port locally, forwarding to 5000 in the pod # Listen on a random port locally, forwarding to 5000 in the pod
kubectl port-forward mypod :5000 kubectl port-forward mypod :5000
# Listen on a random port locally, forwarding to 5000 in the pod # Listen on a random port locally, forwarding to 5000 in the pod
kubectl port-forward mypod 0:5000` kubectl port-forward mypod 0:5000`)
) )
func NewCmdPortForward(f *cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command { func NewCmdPortForward(f *cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command {

View File

@ -24,45 +24,48 @@ import (
"strings" "strings"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
default_port = 8001 default_port = 8001
proxy_example = `# Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/ proxy_example = dedent.Dedent(`
kubectl proxy --port=8011 --www=./local/www/ # Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/
kubectl proxy --port=8011 --www=./local/www/
# Run a proxy to kubernetes apiserver on an arbitrary local port. # Run a proxy to kubernetes apiserver on an arbitrary local port.
# The chosen port for the server will be output to stdout. # The chosen port for the server will be output to stdout.
kubectl proxy --port=0 kubectl proxy --port=0
# Run a proxy to kubernetes apiserver, changing the api prefix to k8s-api # Run a proxy to kubernetes apiserver, changing the api prefix to k8s-api
# This makes e.g. the pods api available at localhost:8011/k8s-api/v1/pods/ # This makes e.g. the pods api available at localhost:8011/k8s-api/v1/pods/
kubectl proxy --api-prefix=/k8s-api` kubectl proxy --api-prefix=/k8s-api`)
) )
func NewCmdProxy(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdProxy(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]", Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
Short: "Run a proxy to the Kubernetes API server", Short: "Run a proxy to the Kubernetes API server",
Long: `To proxy all of the kubernetes api and nothing else, use: Long: dedent.Dedent(`
To proxy all of the kubernetes api and nothing else, use:
kubectl proxy --api-prefix=/ kubectl proxy --api-prefix=/
To proxy only part of the kubernetes api and also some static files: To proxy only part of the kubernetes api and also some static files:
kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/ kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/
The above lets you 'curl localhost:8001/api/v1/pods'. The above lets you 'curl localhost:8001/api/v1/pods'.
To proxy the entire kubernetes api at a different root, use: To proxy the entire kubernetes api at a different root, use:
kubectl proxy --api-prefix=/custom/ kubectl proxy --api-prefix=/custom/
The above lets you 'curl localhost:8001/custom/api/v1/pods' The above lets you 'curl localhost:8001/custom/api/v1/pods'
`, `),
Example: proxy_example, Example: proxy_example,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
err := RunProxy(f, out, cmd) err := RunProxy(f, out, cmd)

View File

@ -23,6 +23,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/golang/glog" "github.com/golang/glog"
@ -38,25 +39,27 @@ type ReplaceOptions struct {
Recursive bool Recursive bool
} }
const ( var (
replace_long = `Replace a resource by filename or stdin. replace_long = dedent.Dedent(`
Replace a resource by filename or stdin.
JSON and YAML formats are accepted. If replacing an existing resource, the JSON and YAML formats are accepted. If replacing an existing resource, the
complete resource spec must be provided. This can be obtained by complete resource spec must be provided. This can be obtained by
$ kubectl get TYPE NAME -o yaml $ kubectl get TYPE NAME -o yaml
Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.` Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.`)
replace_example = `# Replace a pod using the data in pod.json. replace_example = dedent.Dedent(`
kubectl replace -f ./pod.json # Replace a pod using the data in pod.json.
kubectl replace -f ./pod.json
# Replace a pod based on the JSON passed into stdin. # Replace a pod based on the JSON passed into stdin.
cat pod.json | kubectl replace -f - cat pod.json | kubectl replace -f -
# Update a single-container pod's image version (tag) to v4 # Update a single-container pod's image version (tag) to v4
kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f - kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
# Force replace, delete and then re-create the resource # Force replace, delete and then re-create the resource
kubectl replace --force -f ./pod.json` kubectl replace --force -f ./pod.json`)
) )
func NewCmdReplace(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdReplace(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -25,6 +25,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
@ -42,28 +43,30 @@ type RollingUpdateOptions struct {
Filenames []string Filenames []string
} }
const ( var (
rollingUpdate_long = `Perform a rolling update of the given ReplicationController. rollingUpdate_long = dedent.Dedent(`
Perform a rolling update of the given ReplicationController.
Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the
new PodTemplate. The new-controller.json must specify the same namespace as the new PodTemplate. The new-controller.json must specify the same namespace as the
existing replication controller and overwrite at least one (common) label in its replicaSelector.` existing replication controller and overwrite at least one (common) label in its replicaSelector.`)
rollingUpdate_example = `# Update pods of frontend-v1 using new replication controller data in frontend-v2.json. rollingUpdate_example = dedent.Dedent(`
kubectl rolling-update frontend-v1 -f frontend-v2.json # Update pods of frontend-v1 using new replication controller data in frontend-v2.json.
kubectl rolling-update frontend-v1 -f frontend-v2.json
# Update pods of frontend-v1 using JSON data passed into stdin. # Update pods of frontend-v1 using JSON data passed into stdin.
cat frontend-v2.json | kubectl rolling-update frontend-v1 -f - cat frontend-v2.json | kubectl rolling-update frontend-v1 -f -
# Update the pods of frontend-v1 to frontend-v2 by just changing the image, and switching the # Update the pods of frontend-v1 to frontend-v2 by just changing the image, and switching the
# name of the replication controller. # name of the replication controller.
kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2
# Update the pods of frontend by just changing the image, and keeping the old name. # Update the pods of frontend by just changing the image, and keeping the old name.
kubectl rolling-update frontend --image=image:v2 kubectl rolling-update frontend --image=image:v2
# Abort and reverse an existing rollout in progress (from frontend-v1 to frontend-v2). # Abort and reverse an existing rollout in progress (from frontend-v1 to frontend-v2).
kubectl rolling-update frontend-v1 frontend-v2 --rollback kubectl rolling-update frontend-v1 frontend-v2 --rollback
` `)
) )
var ( var (

View File

@ -19,17 +19,21 @@ package rollout
import ( import (
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
rollout_long = `Manages a deployment using subcommands like "kubectl rollout undo deployment/abc"` rollout_long = dedent.Dedent(`
rollout_example = `# Rollback to the previous deployment Manages a deployment using subcommands like "kubectl rollout undo deployment/abc"`)
kubectl rollout undo deployment/abc` rollout_example = dedent.Dedent(`
rollout_valid_resources = `Valid resource types include: # Rollback to the previous deployment
* deployments kubectl rollout undo deployment/abc`)
` rollout_valid_resources = dedent.Dedent(`
Valid resource types include:
* deployments
`)
) )
func NewCmdRollout(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdRollout(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
@ -34,13 +35,15 @@ type HistoryOptions struct {
Recursive bool Recursive bool
} }
const ( var (
history_long = `View previous rollout revisions and configurations.` history_long = dedent.Dedent(`
history_example = `# View the rollout history of a deployment View previous rollout revisions and configurations.`)
kubectl rollout history deployment/abc history_example = dedent.Dedent(`
# View the rollout history of a deployment
kubectl rollout history deployment/abc
# View the details of deployment revision 3 # View the details of deployment revision 3
kubectl rollout history deployment/abc --revision=3` kubectl rollout history deployment/abc --revision=3`)
) )
func NewCmdRolloutHistory(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdRolloutHistory(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -19,6 +19,7 @@ package rollout
import ( import (
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -42,17 +43,19 @@ type PauseConfig struct {
Recursive bool Recursive bool
} }
const ( var (
pause_long = `Mark the provided resource as paused pause_long = dedent.Dedent(`
Mark the provided resource as paused
Paused resources will not be reconciled by a controller. Paused resources will not be reconciled by a controller.
Use \"kubectl rollout resume\" to resume a paused resource. Use \"kubectl rollout resume\" to resume a paused resource.
Currently only deployments support being paused.` Currently only deployments support being paused.`)
pause_example = `# Mark the nginx deployment as paused. Any current state of pause_example = dedent.Dedent(`
# the deployment will continue its function, new updates to the deployment will not # Mark the nginx deployment as paused. Any current state of
# have an effect as long as the deployment is paused. # the deployment will continue its function, new updates to the deployment will not
kubectl rollout pause deployment/nginx` # have an effect as long as the deployment is paused.
kubectl rollout pause deployment/nginx`)
) )
func NewCmdRolloutPause(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdRolloutPause(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -19,6 +19,7 @@ package rollout
import ( import (
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -42,15 +43,17 @@ type ResumeConfig struct {
Recursive bool Recursive bool
} }
const ( var (
resume_long = `Resume a paused resource resume_long = dedent.Dedent(`
Resume a paused resource
Paused resources will not be reconciled by a controller. By resuming a Paused resources will not be reconciled by a controller. By resuming a
resource, we allow it to be reconciled again. resource, we allow it to be reconciled again.
Currently only deployments support being resumed.` Currently only deployments support being resumed.`)
resume_example = `# Resume an already paused deployment resume_example = dedent.Dedent(`
kubectl rollout resume deployment/nginx` # Resume an already paused deployment
kubectl rollout resume deployment/nginx`)
) )
func NewCmdRolloutResume(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdRolloutResume(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
@ -35,10 +36,12 @@ type StatusOptions struct {
Recursive bool Recursive bool
} }
const ( var (
status_long = `Watch the status of current rollout, until it's done.` status_long = dedent.Dedent(`
status_example = `# Watch the rollout status of a deployment Watch the status of current rollout, until it's done.`)
kubectl rollout status deployment/nginx` status_example = dedent.Dedent(`
# Watch the rollout status of a deployment
kubectl rollout status deployment/nginx`)
) )
func NewCmdRolloutStatus(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdRolloutStatus(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -19,6 +19,7 @@ package rollout
import ( import (
"io" "io"
"github.com/renstrom/dedent"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@ -43,13 +44,15 @@ type UndoOptions struct {
Recursive bool Recursive bool
} }
const ( var (
undo_long = `Rollback to a previous rollout.` undo_long = dedent.Dedent(`
undo_example = `# Rollback to the previous deployment Rollback to a previous rollout.`)
kubectl rollout undo deployment/abc undo_example = dedent.Dedent(`
# Rollback to the previous deployment
kubectl rollout undo deployment/abc
# Rollback to deployment revision 3 # Rollback to deployment revision 3
kubectl rollout undo deployment/abc --to-revision=3` kubectl rollout undo deployment/abc --to-revision=3`)
) )
func NewCmdRolloutUndo(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdRolloutUndo(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -22,6 +22,7 @@ import (
"os" "os"
"time" "time"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -35,38 +36,40 @@ import (
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
const ( var (
run_long = `Create and run a particular image, possibly replicated. run_long = dedent.Dedent(`
Creates a deployment or job to manage the created container(s).` Create and run a particular image, possibly replicated.
run_example = `# Start a single instance of nginx. Creates a deployment or job to manage the created container(s).`)
kubectl run nginx --image=nginx run_example = dedent.Dedent(`
# Start a single instance of nginx.
kubectl run nginx --image=nginx
# Start a single instance of hazelcast and let the container expose port 5701 . # Start a single instance of hazelcast and let the container expose port 5701 .
kubectl run hazelcast --image=hazelcast --port=5701 kubectl run hazelcast --image=hazelcast --port=5701
# Start a single instance of hazelcast and set environment variables "DNS_DOMAIN=cluster" and "POD_NAMESPACE=default" in the container. # Start a single instance of hazelcast and set environment variables "DNS_DOMAIN=cluster" and "POD_NAMESPACE=default" in the container.
kubectl run hazelcast --image=hazelcast --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default" kubectl run hazelcast --image=hazelcast --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default"
# Start a replicated instance of nginx. # Start a replicated instance of nginx.
kubectl run nginx --image=nginx --replicas=5 kubectl run nginx --image=nginx --replicas=5
# Dry run. Print the corresponding API objects without creating them. # Dry run. Print the corresponding API objects without creating them.
kubectl run nginx --image=nginx --dry-run kubectl run nginx --image=nginx --dry-run
# Start a single instance of nginx, but overload the spec of the deployment with a partial set of values parsed from JSON. # Start a single instance of nginx, but overload the spec of the deployment with a partial set of values parsed from JSON.
kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }' kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }'
# Start a pod of busybox and keep it in the foreground, don't restart it if it exits. # Start a pod of busybox and keep it in the foreground, don't restart it if it exits.
kubectl run -i -t busybox --image=busybox --restart=Never kubectl run -i -t busybox --image=busybox --restart=Never
# Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command. # Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command.
kubectl run nginx --image=nginx -- <arg1> <arg2> ... <argN> kubectl run nginx --image=nginx -- <arg1> <arg2> ... <argN>
# Start the nginx container using a different command and custom arguments. # Start the nginx container using a different command and custom arguments.
kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN> kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>
# Start the perl container to compute π to 2000 places and print it out. # Start the perl container to compute π to 2000 places and print it out.
kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print bpi(2000)'` kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print bpi(2000)'`)
) )
func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command { func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {

View File

@ -21,6 +21,7 @@ import (
"io" "io"
"os" "os"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@ -36,27 +37,29 @@ type ScaleOptions struct {
Recursive bool Recursive bool
} }
const ( var (
scale_long = `Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job. scale_long = dedent.Dedent(`
Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job.
Scale also allows users to specify one or more preconditions for the scale action. Scale also allows users to specify one or more preconditions for the scale action.
If --current-replicas or --resource-version is specified, it is validated before the If --current-replicas or --resource-version is specified, it is validated before the
scale is attempted, and it is guaranteed that the precondition holds true when the scale is attempted, and it is guaranteed that the precondition holds true when the
scale is sent to the server.` scale is sent to the server.`)
scale_example = `# Scale a replicaset named 'foo' to 3. scale_example = dedent.Dedent(`
kubectl scale --replicas=3 rs/foo # Scale a replicaset named 'foo' to 3.
kubectl scale --replicas=3 rs/foo
# Scale a resource identified by type and name specified in "foo.yaml" to 3. # Scale a resource identified by type and name specified in "foo.yaml" to 3.
kubectl scale --replicas=3 -f foo.yaml kubectl scale --replicas=3 -f foo.yaml
# If the deployment named mysql's current size is 2, scale mysql to 3. # If the deployment named mysql's current size is 2, scale mysql to 3.
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql kubectl scale --current-replicas=2 --replicas=3 deployment/mysql
# Scale multiple replication controllers. # Scale multiple replication controllers.
kubectl scale --replicas=5 rc/foo rc/bar rc/baz kubectl scale --replicas=5 rc/foo rc/bar rc/baz
# Scale job named 'cron' to 3. # Scale job named 'cron' to 3.
kubectl scale --replicas=3 job/cron` kubectl scale --replicas=3 job/cron`)
) )
// NewCmdScale returns a cobra command with the appropriate configuration and flags to run scale // NewCmdScale returns a cobra command with the appropriate configuration and flags to run scale

View File

@ -19,15 +19,17 @@ package set
import ( import (
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
const ( var (
set_long = `Configure application resources set_long = dedent.Dedent(`
Configure application resources
These commands help you make changes to existing application resources.` These commands help you make changes to existing application resources.`)
set_example = `` set_example = dedent.Dedent(``)
) )
func NewCmdSet(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdSet(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -55,25 +56,27 @@ type ImageOptions struct {
ContainerImages map[string]string ContainerImages map[string]string
} }
const ( var (
image_resources = ` image_resources = `
pod (po), replicationcontroller (rc), deployment, daemonset (ds), job, replicaset (rs)` pod (po), replicationcontroller (rc), deployment, daemonset (ds), job, replicaset (rs)`
image_long = `Update existing container image(s) of resources. image_long = dedent.Dedent(`
Update existing container image(s) of resources.
Possible resources include (case insensitive):` + image_resources Possible resources include (case insensitive):`) + image_resources
image_example = `# Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'. image_example = dedent.Dedent(`
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1 # Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'.
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
# Update all deployments' and rc's nginx container's image to 'nginx:1.9.1' # Update all deployments' and rc's nginx container's image to 'nginx:1.9.1'
kubectl set image deployments,rc nginx=nginx:1.9.1 --all kubectl set image deployments,rc nginx=nginx:1.9.1 --all
# Update image of all containers of daemonset abc to 'nginx:1.9.1' # Update image of all containers of daemonset abc to 'nginx:1.9.1'
kubectl set image daemonset abc *=nginx:1.9.1 kubectl set image daemonset abc *=nginx:1.9.1
# Print result (in yaml format) of updating nginx container image from local file, without hitting the server # Print result (in yaml format) of updating nginx container image from local file, without hitting the server
kubectl set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml` kubectl set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml`)
) )
func NewCmdImage(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdImage(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@ -33,25 +34,27 @@ type StopOptions struct {
Recursive bool Recursive bool
} }
const ( var (
stop_long = `Deprecated: Gracefully shut down a resource by name or filename. stop_long = dedent.Dedent(`
Deprecated: Gracefully shut down a resource by name or filename.
The stop command is deprecated, all its functionalities are covered by delete command. The stop command is deprecated, all its functionalities are covered by delete command.
See 'kubectl delete --help' for more details. See 'kubectl delete --help' for more details.
Attempts to shut down and delete a resource that supports graceful termination. Attempts to shut down and delete a resource that supports graceful termination.
If the resource is scalable it will be scaled to 0 before deletion.` If the resource is scalable it will be scaled to 0 before deletion.`)
stop_example = `# Shut down foo. stop_example = dedent.Dedent(`
kubectl stop replicationcontroller foo # Shut down foo.
kubectl stop replicationcontroller foo
# Stop pods and services with label name=myLabel. # Stop pods and services with label name=myLabel.
kubectl stop pods,services -l name=myLabel kubectl stop pods,services -l name=myLabel
# Shut down the service defined in service.json # Shut down the service defined in service.json
kubectl stop -f service.json kubectl stop -f service.json
# Shut down all resources in the path/to/resources directory # Shut down all resources in the path/to/resources directory
kubectl stop -f path/to/resources` kubectl stop -f path/to/resources`)
) )
func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command {

View File

@ -23,6 +23,7 @@ import (
"encoding/json" "encoding/json"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -49,19 +50,21 @@ type TaintOptions struct {
cmd *cobra.Command cmd *cobra.Command
} }
const ( var (
taint_long = `Update the taints on one or more nodes. taint_long = dedent.Dedent(`
Update the taints on one or more nodes.
A taint consists of a key, value, and effect. As an argument here, it is expressed as key=value:effect. A taint consists of a key, value, and effect. As an argument here, it is expressed as key=value:effect.
The key must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters. The key must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
The value must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters. The value must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
The effect must be NoSchedule or PreferNoSchedule. The effect must be NoSchedule or PreferNoSchedule.
Currently taint can only apply to node.` Currently taint can only apply to node.`)
taint_example = `# Update node 'foo' with a taint with key 'dedicated' and value 'special-user' and effect 'NoSchedule'. taint_example = dedent.Dedent(`
# If a taint with that key already exists, its value and effect are replaced as specified. # Update node 'foo' with a taint with key 'dedicated' and value 'special-user' and effect 'NoSchedule'.
kubectl taint nodes foo dedicated=special-user:NoSchedule # If a taint with that key already exists, its value and effect are replaced as specified.
# Remove from node 'foo' the taint with key 'dedicated' if one exists. kubectl taint nodes foo dedicated=special-user:NoSchedule
kubectl taint nodes foo dedicated-` # Remove from node 'foo' the taint with key 'dedicated' if one exists.
kubectl taint nodes foo dedicated-`)
) )
func NewCmdTaint(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdTaint(f *cmdutil.Factory, out io.Writer) *cobra.Command {

11
vendor/github.com/renstrom/dedent/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,11 @@
language: go
go:
- 1.0
- 1.1
- 1.2
- 1.3
- 1.4
- 1.5
sudo: false

21
vendor/github.com/renstrom/dedent/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Peter Renström
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

50
vendor/github.com/renstrom/dedent/README.md generated vendored Normal file
View File

@ -0,0 +1,50 @@
# Dedent
[![Build Status](https://travis-ci.org/renstrom/dedent.svg?branch=master)](https://travis-ci.org/renstrom/dedent)
[![Godoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/renstrom/dedent)
Removes common leading whitespace from multiline strings. Inspired by [`textwrap.dedent`](https://docs.python.org/3/library/textwrap.html#textwrap.dedent) in Python.
## Usage / example
Imagine the following snippet that prints a multiline string. You want the indentation to both look nice in the code as well as in the actual output.
```go
package main
import (
"fmt"
"github.com/renstrom/dedent"
)
func main() {
s := `Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Curabitur justo tellus, facilisis nec efficitur dictum,
fermentum vitae ligula. Sed eu convallis sapien.`
fmt.Println(dedent.Dedent(s))
fmt.Println("-------------")
fmt.Println(s)
}
```
To illustrate the difference, here's the output:
```bash
$ go run main.go
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Curabitur justo tellus, facilisis nec efficitur dictum,
fermentum vitae ligula. Sed eu convallis sapien.
-------------
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Curabitur justo tellus, facilisis nec efficitur dictum,
fermentum vitae ligula. Sed eu convallis sapien.
```
## License
MIT

49
vendor/github.com/renstrom/dedent/dedent.go generated vendored Normal file
View File

@ -0,0 +1,49 @@
package dedent
import (
"regexp"
"strings"
)
var (
whitespaceOnly = regexp.MustCompile("(?m)^[ \t]+$")
leadingWhitespace = regexp.MustCompile("(?m)(^[ \t]*)(?:[^ \t\n])")
)
// Dedent removes any common leading whitespace from every line in text.
//
// This can be used to make multiline strings to line up with the left edge of
// the display, while still presenting them in the source code in indented
// form.
func Dedent(text string) string {
var margin string
text = whitespaceOnly.ReplaceAllString(text, "")
indents := leadingWhitespace.FindAllStringSubmatch(text, -1)
// Look for the longest leading string of spaces and tabs common to all
// lines.
for i, indent := range indents {
if i == 0 {
margin = indent[1]
} else if strings.HasPrefix(indent[1], margin) {
// Current line more deeply indented than previous winner:
// no change (previous winner is still on top).
continue
} else if strings.HasPrefix(margin, indent[1]) {
// Current line consistent with and no deeper than previous winner:
// it's the new winner.
margin = indent[1]
} else {
// Current line and previous winner have no common whitespace:
// there is no margin.
margin = ""
break
}
}
if margin != "" {
text = regexp.MustCompile("(?m)^"+margin).ReplaceAllString(text, "")
}
return text
}