mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
Merge pull request #10374 from caesarxuchao/add-cmd-patch
Add `kubetcl patch`
This commit is contained in:
commit
7ad50cf02c
@ -350,6 +350,27 @@ _kubectl_replace()
|
|||||||
must_have_one_noun=()
|
must_have_one_noun=()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_kubectl_patch()
|
||||||
|
{
|
||||||
|
last_command="kubectl_patch"
|
||||||
|
commands=()
|
||||||
|
|
||||||
|
flags=()
|
||||||
|
two_word_flags=()
|
||||||
|
flags_with_completion=()
|
||||||
|
flags_completion=()
|
||||||
|
|
||||||
|
flags+=("--help")
|
||||||
|
flags+=("-h")
|
||||||
|
flags+=("--patch=")
|
||||||
|
two_word_flags+=("-p")
|
||||||
|
|
||||||
|
must_have_one_flag=()
|
||||||
|
must_have_one_flag+=("--patch=")
|
||||||
|
must_have_one_flag+=("-p")
|
||||||
|
must_have_one_noun=()
|
||||||
|
}
|
||||||
|
|
||||||
_kubectl_delete()
|
_kubectl_delete()
|
||||||
{
|
{
|
||||||
last_command="kubectl_delete"
|
last_command="kubectl_delete"
|
||||||
@ -905,6 +926,7 @@ _kubectl()
|
|||||||
commands+=("describe")
|
commands+=("describe")
|
||||||
commands+=("create")
|
commands+=("create")
|
||||||
commands+=("replace")
|
commands+=("replace")
|
||||||
|
commands+=("patch")
|
||||||
commands+=("delete")
|
commands+=("delete")
|
||||||
commands+=("namespace")
|
commands+=("namespace")
|
||||||
commands+=("logs")
|
commands+=("logs")
|
||||||
|
@ -18,6 +18,7 @@ kubectl_get.md
|
|||||||
kubectl_label.md
|
kubectl_label.md
|
||||||
kubectl_logs.md
|
kubectl_logs.md
|
||||||
kubectl_namespace.md
|
kubectl_namespace.md
|
||||||
|
kubectl_patch.md
|
||||||
kubectl_port-forward.md
|
kubectl_port-forward.md
|
||||||
kubectl_proxy.md
|
kubectl_proxy.md
|
||||||
kubectl_replace.md
|
kubectl_replace.md
|
||||||
|
@ -56,6 +56,7 @@ kubectl
|
|||||||
* [kubectl label](kubectl_label.md) - Update the labels on a resource
|
* [kubectl label](kubectl_label.md) - Update the labels on a resource
|
||||||
* [kubectl logs](kubectl_logs.md) - Print the logs for a container in a pod.
|
* [kubectl logs](kubectl_logs.md) - Print the logs for a container in a pod.
|
||||||
* [kubectl namespace](kubectl_namespace.md) - SUPERCEDED: Set and view the current Kubernetes namespace
|
* [kubectl namespace](kubectl_namespace.md) - SUPERCEDED: Set and view the current Kubernetes namespace
|
||||||
|
* [kubectl patch](kubectl_patch.md) - Update field(s) of a resource by stdin.
|
||||||
* [kubectl port-forward](kubectl_port-forward.md) - Forward one or more local ports to a pod.
|
* [kubectl port-forward](kubectl_port-forward.md) - Forward one or more local ports to a pod.
|
||||||
* [kubectl proxy](kubectl_proxy.md) - Run a proxy to the Kubernetes API server
|
* [kubectl proxy](kubectl_proxy.md) - Run a proxy to the Kubernetes API server
|
||||||
* [kubectl replace](kubectl_replace.md) - Replace a resource by filename or stdin.
|
* [kubectl replace](kubectl_replace.md) - Replace a resource by filename or stdin.
|
||||||
@ -65,6 +66,6 @@ kubectl
|
|||||||
* [kubectl stop](kubectl_stop.md) - Gracefully shut down a resource by id or filename.
|
* [kubectl stop](kubectl_stop.md) - Gracefully shut down a resource by id or filename.
|
||||||
* [kubectl version](kubectl_version.md) - Print the client and server version information.
|
* [kubectl version](kubectl_version.md) - Print the client and server version information.
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra at 2015-06-29 00:10:06.115525904 +0000 UTC
|
###### Auto generated by spf13/cobra at 2015-06-29 23:26:32.294787115 +0000 UTC
|
||||||
|
|
||||||
[]()
|
[]()
|
||||||
|
65
docs/kubectl_patch.md
Normal file
65
docs/kubectl_patch.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
## kubectl patch
|
||||||
|
|
||||||
|
Update field(s) of a resource by stdin.
|
||||||
|
|
||||||
|
### Synopsis
|
||||||
|
|
||||||
|
|
||||||
|
Update field(s) of a resource using strategic merge patch
|
||||||
|
|
||||||
|
JSON and YAML formats are accepted.
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl patch RESOURCE NAME -p PATCH
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
// Partially update a node using strategic merge patch
|
||||||
|
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-h, --help=false: help for patch
|
||||||
|
-p, --patch="": The patch to be appied to the resource JSON file.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options inherited from parent commands
|
||||||
|
|
||||||
|
```
|
||||||
|
--alsologtostderr=false: log to standard error as well as files
|
||||||
|
--api-version="": The API version to use when talking to the server
|
||||||
|
--certificate-authority="": Path to a cert. file for the certificate authority.
|
||||||
|
--client-certificate="": Path to a client key file for TLS.
|
||||||
|
--client-key="": Path to a client key file for TLS.
|
||||||
|
--cluster="": The name of the kubeconfig cluster to use
|
||||||
|
--context="": The name of the kubeconfig context to use
|
||||||
|
--insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.
|
||||||
|
--kubeconfig="": Path to the kubeconfig file to use for CLI requests.
|
||||||
|
--log-backtrace-at=:0: when logging hits line file:N, emit a stack trace
|
||||||
|
--log-dir=: If non-empty, write log files in this directory
|
||||||
|
--log-flush-frequency=5s: Maximum number of seconds between log flushes
|
||||||
|
--logtostderr=true: log to standard error instead of files
|
||||||
|
--match-server-version=false: Require server version to match client version
|
||||||
|
--namespace="": If present, the namespace scope for this CLI request.
|
||||||
|
--password="": Password for basic authentication to the API server.
|
||||||
|
-s, --server="": The address and port of the Kubernetes API server
|
||||||
|
--stderrthreshold=2: logs at or above this threshold go to stderr
|
||||||
|
--token="": Bearer token for authentication to the API server.
|
||||||
|
--user="": The name of the kubeconfig user to use
|
||||||
|
--username="": Username for basic authentication to the API server.
|
||||||
|
--v=0: log level for V logs
|
||||||
|
--validate=false: If true, use a schema to validate the input before sending it
|
||||||
|
--vmodule=: comma-separated list of pattern=N settings for file-filtered logging
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||||
|
|
||||||
|
###### Auto generated by spf13/cobra at 2015-06-26 01:21:14.985174217 +0000 UTC
|
||||||
|
|
||||||
|
[]()
|
@ -17,6 +17,7 @@ kubectl-get.1
|
|||||||
kubectl-label.1
|
kubectl-label.1
|
||||||
kubectl-logs.1
|
kubectl-logs.1
|
||||||
kubectl-namespace.1
|
kubectl-namespace.1
|
||||||
|
kubectl-patch.1
|
||||||
kubectl-port-forward.1
|
kubectl-port-forward.1
|
||||||
kubectl-proxy.1
|
kubectl-proxy.1
|
||||||
kubectl-replace.1
|
kubectl-replace.1
|
||||||
|
150
docs/man/man1/kubectl-patch.1
Normal file
150
docs/man/man1/kubectl-patch.1
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" ""
|
||||||
|
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
.PP
|
||||||
|
kubectl patch \- Update field(s) of a resource by stdin.
|
||||||
|
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.PP
|
||||||
|
\fBkubectl patch\fP [OPTIONS]
|
||||||
|
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.PP
|
||||||
|
Update field(s) of a resource using strategic merge patch
|
||||||
|
|
||||||
|
.PP
|
||||||
|
JSON and YAML formats are accepted.
|
||||||
|
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.PP
|
||||||
|
\fB\-h\fP, \fB\-\-help\fP=false
|
||||||
|
help for patch
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-p\fP, \fB\-\-patch\fP=""
|
||||||
|
The patch to be appied to the resource JSON file.
|
||||||
|
|
||||||
|
|
||||||
|
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||||
|
.PP
|
||||||
|
\fB\-\-alsologtostderr\fP=false
|
||||||
|
log to standard error as well as files
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-api\-version\fP=""
|
||||||
|
The API version to use when talking to the server
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-certificate\-authority\fP=""
|
||||||
|
Path to a cert. file for the certificate authority.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-client\-certificate\fP=""
|
||||||
|
Path to a client key file for TLS.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-client\-key\fP=""
|
||||||
|
Path to a client key file for TLS.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-cluster\fP=""
|
||||||
|
The name of the kubeconfig cluster to use
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-context\fP=""
|
||||||
|
The name of the kubeconfig context to use
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-insecure\-skip\-tls\-verify\fP=false
|
||||||
|
If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-kubeconfig\fP=""
|
||||||
|
Path to the kubeconfig file to use for CLI requests.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-log\-backtrace\-at\fP=:0
|
||||||
|
when logging hits line file:N, emit a stack trace
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-log\-dir\fP=""
|
||||||
|
If non\-empty, write log files in this directory
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-log\-flush\-frequency\fP=5s
|
||||||
|
Maximum number of seconds between log flushes
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-logtostderr\fP=true
|
||||||
|
log to standard error instead of files
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-match\-server\-version\fP=false
|
||||||
|
Require server version to match client version
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-namespace\fP=""
|
||||||
|
If present, the namespace scope for this CLI request.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-password\fP=""
|
||||||
|
Password for basic authentication to the API server.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-s\fP, \fB\-\-server\fP=""
|
||||||
|
The address and port of the Kubernetes API server
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-stderrthreshold\fP=2
|
||||||
|
logs at or above this threshold go to stderr
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-token\fP=""
|
||||||
|
Bearer token for authentication to the API server.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-user\fP=""
|
||||||
|
The name of the kubeconfig user to use
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-username\fP=""
|
||||||
|
Username for basic authentication to the API server.
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-v\fP=0
|
||||||
|
log level for V logs
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-validate\fP=false
|
||||||
|
If true, use a schema to validate the input before sending it
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-vmodule\fP=
|
||||||
|
comma\-separated list of pattern=N settings for file\-filtered logging
|
||||||
|
|
||||||
|
|
||||||
|
.SH EXAMPLE
|
||||||
|
.PP
|
||||||
|
.RS
|
||||||
|
|
||||||
|
.nf
|
||||||
|
|
||||||
|
// Partially update a node using strategic merge patch
|
||||||
|
kubectl patch node k8s\-node\-1 \-p '\{"spec":\{"unschedulable":true\}\}'
|
||||||
|
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
|
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.PP
|
||||||
|
\fBkubectl(1)\fP,
|
||||||
|
|
||||||
|
|
||||||
|
.SH HISTORY
|
||||||
|
.PP
|
||||||
|
January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since!
|
@ -124,7 +124,7 @@ Find more information at
|
|||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.PP
|
.PP
|
||||||
\fBkubectl\-get(1)\fP, \fBkubectl\-describe(1)\fP, \fBkubectl\-create(1)\fP, \fBkubectl\-replace(1)\fP, \fBkubectl\-delete(1)\fP, \fBkubectl\-namespace(1)\fP, \fBkubectl\-logs(1)\fP, \fBkubectl\-rolling\-update(1)\fP, \fBkubectl\-scale(1)\fP, \fBkubectl\-exec(1)\fP, \fBkubectl\-port\-forward(1)\fP, \fBkubectl\-proxy(1)\fP, \fBkubectl\-run(1)\fP, \fBkubectl\-stop(1)\fP, \fBkubectl\-expose(1)\fP, \fBkubectl\-label(1)\fP, \fBkubectl\-config(1)\fP, \fBkubectl\-cluster\-info(1)\fP, \fBkubectl\-api\-versions(1)\fP, \fBkubectl\-version(1)\fP,
|
\fBkubectl\-get(1)\fP, \fBkubectl\-describe(1)\fP, \fBkubectl\-create(1)\fP, \fBkubectl\-replace(1)\fP, \fBkubectl\-patch(1)\fP, \fBkubectl\-delete(1)\fP, \fBkubectl\-namespace(1)\fP, \fBkubectl\-logs(1)\fP, \fBkubectl\-rolling\-update(1)\fP, \fBkubectl\-scale(1)\fP, \fBkubectl\-exec(1)\fP, \fBkubectl\-port\-forward(1)\fP, \fBkubectl\-proxy(1)\fP, \fBkubectl\-run(1)\fP, \fBkubectl\-stop(1)\fP, \fBkubectl\-expose(1)\fP, \fBkubectl\-label(1)\fP, \fBkubectl\-config(1)\fP, \fBkubectl\-cluster\-info(1)\fP, \fBkubectl\-api\-versions(1)\fP, \fBkubectl\-version(1)\fP,
|
||||||
|
|
||||||
|
|
||||||
.SH HISTORY
|
.SH HISTORY
|
||||||
|
@ -378,12 +378,19 @@ for version in "${kube_api_versions[@]}"; do
|
|||||||
# Post-condition: valid-pod POD is running
|
# Post-condition: valid-pod POD is running
|
||||||
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
|
kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
|
||||||
|
|
||||||
|
## Patch pod can change image
|
||||||
|
# Command
|
||||||
|
kubectl patch "${kube_flags[@]}" pod valid-pod -p='{"spec":{"containers":[{"name": "kubernetes-serve-hostname", "image": "nginx"}]}}'
|
||||||
|
# Post-condition: valid-pod POD has image nginx
|
||||||
|
kube::test::get_object_assert pods "{{range.items}}{{$image_field}}:{{end}}" 'nginx:'
|
||||||
|
|
||||||
## --force replace pod can change other field, e.g., spec.container.name
|
## --force replace pod can change other field, e.g., spec.container.name
|
||||||
# Command
|
# Command
|
||||||
kubectl get "${kube_flags[@]}" pod valid-pod -o json | sed 's/"kubernetes-serve-hostname"/"replaced-k8s-serve-hostname"/g' > tmp-valid-pod.json
|
kubectl get "${kube_flags[@]}" pod valid-pod -o json | sed 's/"kubernetes-serve-hostname"/"replaced-k8s-serve-hostname"/g' > tmp-valid-pod.json
|
||||||
kubectl replace "${kube_flags[@]}" --force -f tmp-valid-pod.json
|
kubectl replace "${kube_flags[@]}" --force -f tmp-valid-pod.json
|
||||||
# Post-condition: spec.container.name = "replaced-k8s-serve-hostname"
|
# Post-condition: spec.container.name = "replaced-k8s-serve-hostname"
|
||||||
kube::test::get_object_assert 'pod valid-pod' "{{(index .spec.containers 0).name}}" 'replaced-k8s-serve-hostname'
|
kube::test::get_object_assert 'pod valid-pod' "{{(index .spec.containers 0).name}}" 'replaced-k8s-serve-hostname'
|
||||||
|
rm tmp-valid-pod.json
|
||||||
|
|
||||||
### Overwriting an existing label is not permitted
|
### Overwriting an existing label is not permitted
|
||||||
# Pre-condition: name is valid-pod
|
# Pre-condition: name is valid-pod
|
||||||
@ -718,6 +725,16 @@ __EOF__
|
|||||||
|
|
||||||
kube::test::describe_object_assert nodes "127.0.0.1" "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
|
kube::test::describe_object_assert nodes "127.0.0.1" "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
|
||||||
|
|
||||||
|
### kubectl patch update can mark node unschedulable
|
||||||
|
# Pre-condition: node is schedulable
|
||||||
|
kube::test::get_object_assert "nodes 127.0.0.1" "{{.spec.unschedulable}}" '<no value>'
|
||||||
|
kubectl patch "${kube_flags[@]}" nodes "127.0.0.1" -p='{"spec":{"unschedulable":true}}'
|
||||||
|
# Post-condition: node is unschedulable
|
||||||
|
kube::test::get_object_assert "nodes 127.0.0.1" "{{.spec.unschedulable}}" 'true'
|
||||||
|
kubectl patch "${kube_flags[@]}" nodes "127.0.0.1" -p='{"spec":{"unschedulable":null}}'
|
||||||
|
# Post-condition: node is schedulable
|
||||||
|
kube::test::get_object_assert "nodes 127.0.0.1" "{{.spec.unschedulable}}" '<no value>'
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# Nodes #
|
# Nodes #
|
||||||
###########
|
###########
|
||||||
|
@ -115,6 +115,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
|||||||
cmds.AddCommand(NewCmdDescribe(f, out))
|
cmds.AddCommand(NewCmdDescribe(f, out))
|
||||||
cmds.AddCommand(NewCmdCreate(f, out))
|
cmds.AddCommand(NewCmdCreate(f, out))
|
||||||
cmds.AddCommand(NewCmdReplace(f, out))
|
cmds.AddCommand(NewCmdReplace(f, out))
|
||||||
|
cmds.AddCommand(NewCmdPatch(f, out))
|
||||||
cmds.AddCommand(NewCmdDelete(f, out))
|
cmds.AddCommand(NewCmdDelete(f, out))
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdNamespace(out))
|
cmds.AddCommand(NewCmdNamespace(out))
|
||||||
|
99
pkg/kubectl/cmd/patch.go
Normal file
99
pkg/kubectl/cmd/patch.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
patch_long = `Update field(s) of a resource using strategic merge patch
|
||||||
|
|
||||||
|
JSON and YAML formats are accepted.`
|
||||||
|
patch_example = `
|
||||||
|
// Partially update a node using strategic merge patch
|
||||||
|
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'`
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "patch RESOURCE NAME -p PATCH",
|
||||||
|
Short: "Update field(s) of a resource by stdin.",
|
||||||
|
Long: patch_long,
|
||||||
|
Example: patch_example,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
err := RunPatch(f, out, cmd, args)
|
||||||
|
cmdutil.CheckCustomErr("Patch failed", err)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().StringP("patch", "p", "", "The patch to be appied to the resource JSON file.")
|
||||||
|
cmd.MarkFlagRequired("patch")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
|
||||||
|
cmdNamespace, err := f.DefaultNamespace()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
patch := cmdutil.GetFlagString(cmd, "patch")
|
||||||
|
if len(patch) == 0 {
|
||||||
|
return cmdutil.UsageError(cmd, "Must specify -p to patch")
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper, typer := f.Object()
|
||||||
|
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
|
||||||
|
ContinueOnError().
|
||||||
|
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||||
|
ResourceTypeOrNameArgs(false, args...).
|
||||||
|
Flatten().
|
||||||
|
Do()
|
||||||
|
err = r.Err()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mapping, err := r.ResourceMapping()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client, err := f.RESTClient(mapping)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
infos, err := r.Infos()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
name, namespace := infos[0].Name, infos[0].Namespace
|
||||||
|
|
||||||
|
helper := resource.NewHelper(client, mapping)
|
||||||
|
_, err = helper.Patch(namespace, name, api.StrategicMergePatchType, []byte(patch))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, "%s\n", name)
|
||||||
|
return nil
|
||||||
|
}
|
56
pkg/kubectl/cmd/patch_test.go
Normal file
56
pkg/kubectl/cmd/patch_test.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPatchObject(t *testing.T) {
|
||||||
|
_, svc, _ := testData()
|
||||||
|
|
||||||
|
f, tf, codec := NewAPIFactory()
|
||||||
|
tf.Printer = &testPrinter{}
|
||||||
|
tf.Client = &client.FakeRESTClient{
|
||||||
|
Codec: codec,
|
||||||
|
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
|
||||||
|
switch p, m := req.URL.Path, req.Method; {
|
||||||
|
case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"):
|
||||||
|
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
tf.Namespace = "test"
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
|
cmd := NewCmdPatch(f, buf)
|
||||||
|
cmd.Flags().Set("namespace", "test")
|
||||||
|
cmd.Flags().Set("patch", `{"spec":{"type":"NodePort"}}`)
|
||||||
|
cmd.Run(cmd, []string{"services/frontend"})
|
||||||
|
|
||||||
|
// uses the name from the file, not the response
|
||||||
|
if buf.String() != "frontend\n" {
|
||||||
|
t.Errorf("unexpected output: %s", buf.String())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user