mirror of https://github.com/k3s-io/k3s
commit
7ad50cf02c
|
@ -350,6 +350,27 @@ _kubectl_replace()
|
|||
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()
|
||||
{
|
||||
last_command="kubectl_delete"
|
||||
|
@ -905,6 +926,7 @@ _kubectl()
|
|||
commands+=("describe")
|
||||
commands+=("create")
|
||||
commands+=("replace")
|
||||
commands+=("patch")
|
||||
commands+=("delete")
|
||||
commands+=("namespace")
|
||||
commands+=("logs")
|
||||
|
|
|
@ -18,6 +18,7 @@ kubectl_get.md
|
|||
kubectl_label.md
|
||||
kubectl_logs.md
|
||||
kubectl_namespace.md
|
||||
kubectl_patch.md
|
||||
kubectl_port-forward.md
|
||||
kubectl_proxy.md
|
||||
kubectl_replace.md
|
||||
|
|
|
@ -56,6 +56,7 @@ kubectl
|
|||
* [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 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 proxy](kubectl_proxy.md) - Run a proxy to the Kubernetes API server
|
||||
* [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 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
|
||||
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/kubectl.md?pixel)]()
|
||||
|
|
|
@ -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
|
||||
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/kubectl_patch.md?pixel)]()
|
|
@ -17,6 +17,7 @@ kubectl-get.1
|
|||
kubectl-label.1
|
||||
kubectl-logs.1
|
||||
kubectl-namespace.1
|
||||
kubectl-patch.1
|
||||
kubectl-port-forward.1
|
||||
kubectl-proxy.1
|
||||
kubectl-replace.1
|
||||
|
|
|
@ -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
|
||||
.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
|
||||
|
|
|
@ -378,12 +378,19 @@ for version in "${kube_api_versions[@]}"; do
|
|||
# Post-condition: valid-pod POD is running
|
||||
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
|
||||
# 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 replace "${kube_flags[@]}" --force -f tmp-valid-pod.json
|
||||
# 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'
|
||||
rm tmp-valid-pod.json
|
||||
|
||||
### Overwriting an existing label is not permitted
|
||||
# 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:"
|
||||
|
||||
### 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 #
|
||||
###########
|
||||
|
|
|
@ -115,6 +115,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
|
|||
cmds.AddCommand(NewCmdDescribe(f, out))
|
||||
cmds.AddCommand(NewCmdCreate(f, out))
|
||||
cmds.AddCommand(NewCmdReplace(f, out))
|
||||
cmds.AddCommand(NewCmdPatch(f, out))
|
||||
cmds.AddCommand(NewCmdDelete(f, out))
|
||||
|
||||
cmds.AddCommand(NewCmdNamespace(out))
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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