Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
e079e23e
Commit
e079e23e
authored
Apr 20, 2015
by
Brendan Burns
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6597 from fabioy/kubectl-validate
Add "kubectl validate" command to do a cluster health check.
parents
ba95c8a1
c6ef2ddf
Hide whitespace changes
Inline
Side-by-side
Showing
56 changed files
with
760 additions
and
137 deletions
+760
-137
validate-cluster.sh
cluster/validate-cluster.sh
+31
-61
kubectl
contrib/completions/bash/kubectl
+1
-0
kubectl.md
docs/kubectl.md
+1
-1
kubectl_api-versions.md
docs/kubectl_api-versions.md
+1
-1
kubectl_cluster-info.md
docs/kubectl_cluster-info.md
+1
-1
kubectl_config.md
docs/kubectl_config.md
+1
-1
kubectl_config_set-cluster.md
docs/kubectl_config_set-cluster.md
+1
-1
kubectl_config_set-context.md
docs/kubectl_config_set-context.md
+1
-1
kubectl_config_set-credentials.md
docs/kubectl_config_set-credentials.md
+1
-1
kubectl_config_set.md
docs/kubectl_config_set.md
+1
-1
kubectl_config_unset.md
docs/kubectl_config_unset.md
+1
-1
kubectl_config_use-context.md
docs/kubectl_config_use-context.md
+1
-1
kubectl_config_view.md
docs/kubectl_config_view.md
+1
-1
kubectl_create.md
docs/kubectl_create.md
+1
-1
kubectl_delete.md
docs/kubectl_delete.md
+1
-1
kubectl_describe.md
docs/kubectl_describe.md
+1
-1
kubectl_exec.md
docs/kubectl_exec.md
+1
-1
kubectl_expose.md
docs/kubectl_expose.md
+1
-1
kubectl_get.md
docs/kubectl_get.md
+2
-2
kubectl_label.md
docs/kubectl_label.md
+1
-1
kubectl_log.md
docs/kubectl_log.md
+1
-1
kubectl_namespace.md
docs/kubectl_namespace.md
+1
-1
kubectl_port-forward.md
docs/kubectl_port-forward.md
+1
-1
kubectl_proxy.md
docs/kubectl_proxy.md
+1
-1
kubectl_resize.md
docs/kubectl_resize.md
+1
-1
kubectl_rolling-update.md
docs/kubectl_rolling-update.md
+1
-1
kubectl_run-container.md
docs/kubectl_run-container.md
+1
-1
kubectl_stop.md
docs/kubectl_stop.md
+1
-1
kubectl_update.md
docs/kubectl_update.md
+1
-1
kubectl_version.md
docs/kubectl_version.md
+1
-1
kubectl-get.1
docs/man/man1/kubectl-get.1
+1
-1
restmapper.go
pkg/api/meta/restmapper.go
+15
-9
register.go
pkg/api/register.go
+4
-0
types.go
pkg/api/types.go
+31
-0
register.go
pkg/api/v1beta1/register.go
+4
-0
types.go
pkg/api/v1beta1/types.go
+29
-0
register.go
pkg/api/v1beta2/register.go
+4
-0
types.go
pkg/api/v1beta2/types.go
+29
-0
register.go
pkg/api/v1beta3/register.go
+4
-0
types.go
pkg/api/v1beta3/types.go
+31
-0
apiserver.go
pkg/apiserver/apiserver.go
+2
-1
validator.go
pkg/apiserver/validator.go
+30
-26
validator_test.go
pkg/apiserver/validator_test.go
+1
-2
client.go
pkg/client/client.go
+24
-0
componentstatuses.go
pkg/client/componentstatuses.go
+63
-0
fake_componentstatuses.go
pkg/client/testclient/fake_componentstatuses.go
+47
-0
testclient.go
pkg/client/testclient/testclient.go
+4
-0
cmd_test.go
pkg/kubectl/cmd/cmd_test.go
+7
-0
get.go
pkg/kubectl/cmd/get.go
+1
-1
get_test.go
pkg/kubectl/cmd/get_test.go
+51
-0
kubectl.go
pkg/kubectl/kubectl.go
+9
-7
resource_printer.go
pkg/kubectl/resource_printer.go
+33
-0
master.go
pkg/master/master.go
+3
-0
doc.go
pkg/registry/componentstatus/doc.go
+19
-0
rest.go
pkg/registry/componentstatus/rest.go
+110
-0
rest_test.go
pkg/registry/componentstatus/rest_test.go
+143
-0
No files found.
cluster/validate-cluster.sh
View file @
e079e23e
...
@@ -14,11 +14,7 @@
...
@@ -14,11 +14,7 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
# Bring up a Kubernetes cluster.
# Validates that the cluster is healthy.
#
# If the full release name (gs://<bucket>/<release>) is passed in then we take
# that directly. If not then we assume we are doing development stuff and take
# the defaults in the release config.
set
-o
errexit
set
-o
errexit
set
-o
nounset
set
-o
nounset
...
@@ -28,12 +24,9 @@ KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
...
@@ -28,12 +24,9 @@ KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
source
"
${
KUBE_ROOT
}
/cluster/kube-env.sh"
source
"
${
KUBE_ROOT
}
/cluster/kube-env.sh"
source
"
${
KUBE_ROOT
}
/cluster/
${
KUBERNETES_PROVIDER
}
/util.sh"
source
"
${
KUBE_ROOT
}
/cluster/
${
KUBERNETES_PROVIDER
}
/util.sh"
get-password
detect-master
>
/dev/null
detect-minions
>
/dev/null
MINIONS_FILE
=
/tmp/minions-
$$
MINIONS_FILE
=
/tmp/minions-
$$
trap
'rm -rf "${MINIONS_FILE}"'
EXIT
trap
'rm -rf "${MINIONS_FILE}"'
EXIT
# Make several attempts to deal with slow cluster birth.
# Make several attempts to deal with slow cluster birth.
attempt
=
0
attempt
=
0
while
true
;
do
while
true
;
do
...
@@ -54,62 +47,39 @@ done
...
@@ -54,62 +47,39 @@ done
echo
"Found
${
found
}
nodes."
echo
"Found
${
found
}
nodes."
cat
-n
"
${
MINIONS_FILE
}
"
cat
-n
"
${
MINIONS_FILE
}
"
# On vSphere, use minion IPs as their names
attempt
=
0
if
[[
"
${
KUBERNETES_PROVIDER
}
"
==
"vsphere"
||
"
${
KUBERNETES_PROVIDER
}
"
==
"vagrant"
||
"
${
KUBERNETES_PROVIDER
}
"
==
"libvirt-coreos"
||
"
${
KUBERNETES_PROVIDER
}
"
==
"juju"
]]
;
then
while
true
;
do
MINION_NAMES
=(
"
${
KUBE_MINION_IP_ADDRESSES
[@]
}
"
)
kubectl_output
=
$(
"
${
KUBE_ROOT
}
/cluster/kubectl.sh"
get componentstatus
)
fi
# On AWS we can't really name the minions, so just trust that if the number is right, the right names are there.
if
[[
"
${
KUBERNETES_PROVIDER
}
"
==
"aws"
]]
;
then
MINION_NAMES
=(
"
$(
cat
${
MINIONS_FILE
})
"
)
# /healthz validation isn't working for some reason on AWS. So just hope for the best.
# TODO: figure out why and fix, it must be working in some form, or else clusters wouldn't work.
echo
"Kubelet health checking on AWS isn't currently supported, assuming everything is good..."
echo
-e
"
${
color_green
}
Cluster validation succeeded
${
color_norm
}
"
exit
0
fi
for
((
i
=
0
;
i<
${#
MINION_NAMES
[@]
}
;
i++
))
;
do
# The "kubectl validate" output is four columns like this:
# Grep returns an exit status of 1 when line is not found, so we need the : to always return a 0 exit status
#
count
=
$(
grep
-c
"
${
MINION_NAMES
[
$i
]
}
"
"
${
MINIONS_FILE
}
"
)
||
:
# COMPONENT HEALTH MSG ERR
if
[[
"
${
count
}
"
==
"0"
]]
;
then
# controller-manager Healthy ok nil
echo
-e
"
${
color_red
}
Failed to find
${
MINION_NAMES
[
$i
]
}
, cluster is probably broken.
${
color_norm
}
"
#
cat
-n
"
${
MINIONS_FILE
}
"
# Parse the output to capture the value of the second column("HEALTH"), then use grep to
exit
1
# count the number of times it doesn't match "success".
fi
# Because of the header, the actual unsuccessful count is 1 minus the count.
name
=
"
${
MINION_NAMES
[
$i
]
}
"
non_success_count
=
$(
echo
"
${
kubectl_output
}
"
|
\
if
[[
"
$KUBERNETES_PROVIDER
"
!=
"vsphere"
&&
"
$KUBERNETES_PROVIDER
"
!=
"vagrant"
&&
"
$KUBERNETES_PROVIDER
"
!=
"libvirt-coreos"
&&
"
$KUBERNETES_PROVIDER
"
!=
"juju"
]]
;
then
sed
-n
's/^\([[:alnum:][:punct:]]\+\)\s\+\([[:alnum:][:punct:]]\+\)\s\+.*/\2/p'
|
\
# Grab fully qualified name
grep
'Healthy'
--invert-match
-c
)
name
=
$(
grep
"
${
MINION_NAMES
[
$i
]
}
\.
"
"
${
MINIONS_FILE
}
"
)
fi
# Make sure the kubelet is healthy.
if
((
non_success_count
>
1
))
;
then
# Make several attempts to deal with slow cluster birth.
if
((
attempt < 5
))
;
then
attempt
=
0
echo
-e
"
${
color_yellow
}
Cluster not working yet.
${
color_norm
}
"
while
true
;
do
echo
-n
"Attempt
$((
attempt+1
))
at checking Kubelet installation on node
${
MINION_NAMES
[
$i
]
}
..."
if
[[
"
$KUBERNETES_PROVIDER
"
!=
"libvirt-coreos"
&&
"
$KUBERNETES_PROVIDER
"
!=
"juju"
]]
;
then
curl_output
=
$(
curl
-s
--insecure
--user
"
${
KUBE_USER
}
:
${
KUBE_PASSWORD
}
"
\
"https://
${
KUBE_MASTER_IP
}
/api/v1beta1/proxy/minions/
${
name
}
/healthz"
)
else
curl_output
=
$(
curl
-s
\
"http://
${
KUBE_MASTER_IP
}
:8080/api/v1beta1/proxy/minions/
${
name
}
/healthz"
)
fi
if
[[
"
${
curl_output
}
"
!=
"ok"
]]
;
then
if
((
attempt
>
5
))
;
then
echo
echo
-e
"
${
color_red
}
Kubelet failed to install on node
${
MINION_NAMES
[
$i
]
}
. Your cluster is unlikely to work correctly."
echo
-e
"Please run ./cluster/kube-down.sh and re-create the cluster. (sorry!)
${
color_norm
}
"
exit
1
fi
else
echo
-e
"
${
color_green
}
[working]
${
color_norm
}
"
break
fi
echo
-e
"
${
color_yellow
}
[not working yet]
${
color_norm
}
"
attempt
=
$((
attempt+1
))
attempt
=
$((
attempt+1
))
sleep
30
sleep
30
done
else
echo
-e
"
${
color_yellow
}
Validate output:
${
color_norm
}
"
echo
"
${
kubectl_output
}
"
echo
-e
"
${
color_red
}
Validation returned one or more failed components. Cluster is probably broken.
${
color_norm
}
"
exit
1
fi
else
break
fi
done
done
echo
"Validate output:"
echo
"
${
kubectl_output
}
"
echo
-e
"
${
color_green
}
Cluster validation succeeded
${
color_norm
}
"
echo
-e
"
${
color_green
}
Cluster validation succeeded
${
color_norm
}
"
contrib/completions/bash/kubectl
View file @
e079e23e
...
@@ -242,6 +242,7 @@ _kubectl_get()
...
@@ -242,6 +242,7 @@ _kubectl_get()
must_have_one_flag
=()
must_have_one_flag
=()
must_have_one_noun
=()
must_have_one_noun
=()
must_have_one_noun+
=(
"componentstatus"
)
must_have_one_noun+
=(
"endpoints"
)
must_have_one_noun+
=(
"endpoints"
)
must_have_one_noun+
=(
"event"
)
must_have_one_noun+
=(
"event"
)
must_have_one_noun+
=(
"limitrange"
)
must_have_one_noun+
=(
"limitrange"
)
...
...
docs/kubectl.md
View file @
e079e23e
...
@@ -66,4 +66,4 @@ kubectl
...
@@ -66,4 +66,4 @@ kubectl
*
[
kubectl update
](
kubectl_update.md
)
- Update a resource by filename or stdin.
*
[
kubectl update
](
kubectl_update.md
)
- Update a resource by filename or stdin.
*
[
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-04-1
6 17:04:37.39254963
2 +0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.48896331
2 +0000 UTC
docs/kubectl_api-versions.md
View file @
e079e23e
...
@@ -50,4 +50,4 @@ kubectl api-versions
...
@@ -50,4 +50,4 @@ kubectl api-versions
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.39227534
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.488505223
+0000 UTC
docs/kubectl_cluster-info.md
View file @
e079e23e
...
@@ -50,4 +50,4 @@ kubectl cluster-info
...
@@ -50,4 +50,4 @@ kubectl cluster-info
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.392162759
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.48831375
+0000 UTC
docs/kubectl_config.md
View file @
e079e23e
...
@@ -63,4 +63,4 @@ kubectl config SUBCOMMAND
...
@@ -63,4 +63,4 @@ kubectl config SUBCOMMAND
*
[
kubectl config use-context
](
kubectl_config_use-context.md
)
- Sets the current-context in a kubeconfig file
*
[
kubectl config use-context
](
kubectl_config_use-context.md
)
- Sets the current-context in a kubeconfig file
*
[
kubectl config view
](
kubectl_config_view.md
)
- displays Merged kubeconfig settings or a specified kubeconfig file.
*
[
kubectl config view
](
kubectl_config_view.md
)
- displays Merged kubeconfig settings or a specified kubeconfig file.
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.392043616
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.488116168
+0000 UTC
docs/kubectl_config_set-cluster.md
View file @
e079e23e
...
@@ -65,4 +65,4 @@ $ kubectl config set-cluster e2e --insecure-skip-tls-verify=true
...
@@ -65,4 +65,4 @@ $ kubectl config set-cluster e2e --insecure-skip-tls-verify=true
### SEE ALSO
### SEE ALSO
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.3911962
9 +0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.48646085
9 +0000 UTC
docs/kubectl_config_set-context.md
View file @
e079e23e
...
@@ -58,4 +58,4 @@ $ kubectl config set-context gce --user=cluster-admin
...
@@ -58,4 +58,4 @@ $ kubectl config set-context gce --user=cluster-admin
### SEE ALSO
### SEE ALSO
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.391488399
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.486736724
+0000 UTC
docs/kubectl_config_set-credentials.md
View file @
e079e23e
...
@@ -78,4 +78,4 @@ $ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt -
...
@@ -78,4 +78,4 @@ $ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt -
### SEE ALSO
### SEE ALSO
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.391323192
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.486604006
+0000 UTC
docs/kubectl_config_set.md
View file @
e079e23e
...
@@ -52,4 +52,4 @@ kubectl config set PROPERTY_NAME PROPERTY_VALUE
...
@@ -52,4 +52,4 @@ kubectl config set PROPERTY_NAME PROPERTY_VALUE
### SEE ALSO
### SEE ALSO
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.391618859
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.486861123
+0000 UTC
docs/kubectl_config_unset.md
View file @
e079e23e
...
@@ -51,4 +51,4 @@ kubectl config unset PROPERTY_NAME
...
@@ -51,4 +51,4 @@ kubectl config unset PROPERTY_NAME
### SEE ALSO
### SEE ALSO
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.391735806
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.487685494
+0000 UTC
docs/kubectl_config_use-context.md
View file @
e079e23e
...
@@ -50,4 +50,4 @@ kubectl config use-context CONTEXT_NAME
...
@@ -50,4 +50,4 @@ kubectl config use-context CONTEXT_NAME
### SEE ALSO
### SEE ALSO
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.391848246
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.487888021
+0000 UTC
docs/kubectl_config_view.md
View file @
e079e23e
...
@@ -72,4 +72,4 @@ $ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2
...
@@ -72,4 +72,4 @@ $ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2
### SEE ALSO
### SEE ALSO
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
*
[
kubectl config
](
kubectl_config.md
)
- config modifies kubeconfig files
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.391073075
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.486319118
+0000 UTC
docs/kubectl_create.md
View file @
e079e23e
...
@@ -63,4 +63,4 @@ $ cat pod.json | kubectl create -f -
...
@@ -63,4 +63,4 @@ $ cat pod.json | kubectl create -f -
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.388588064
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.48343431
+0000 UTC
docs/kubectl_delete.md
View file @
e079e23e
...
@@ -81,4 +81,4 @@ $ kubectl delete pods --all
...
@@ -81,4 +81,4 @@ $ kubectl delete pods --all
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.389412973
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.483731878
+0000 UTC
docs/kubectl_describe.md
View file @
e079e23e
...
@@ -53,4 +53,4 @@ kubectl describe RESOURCE ID
...
@@ -53,4 +53,4 @@ kubectl describe RESOURCE ID
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.388410556
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.483293174
+0000 UTC
docs/kubectl_exec.md
View file @
e079e23e
...
@@ -64,4 +64,4 @@ $ kubectl exec -p 123456-7890 -c ruby-container -i -t -- bash -il
...
@@ -64,4 +64,4 @@ $ kubectl exec -p 123456-7890 -c ruby-container -i -t -- bash -il
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.390127525
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.484697863
+0000 UTC
docs/kubectl_expose.md
View file @
e079e23e
...
@@ -82,4 +82,4 @@ $ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream
...
@@ -82,4 +82,4 @@ $ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.390792874
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.485803902
+0000 UTC
docs/kubectl_get.md
View file @
e079e23e
...
@@ -8,7 +8,7 @@ Display one or many resources
...
@@ -8,7 +8,7 @@ Display one or many resources
Display one or many resources.
Display one or many resources.
Possible resources include pods (po), replication controllers (rc), services
Possible resources include pods (po), replication controllers (rc), services
(svc), minions (mi),
or events (ev
).
(svc), minions (mi),
events (ev), or component statuses (cs
).
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).
...
@@ -85,4 +85,4 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7
...
@@ -85,4 +85,4 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.38748307
4 +0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.48258906
4 +0000 UTC
docs/kubectl_label.md
View file @
e079e23e
...
@@ -81,4 +81,4 @@ $ kubectl label pods foo bar-
...
@@ -81,4 +81,4 @@ $ kubectl label pods foo bar-
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.390937166
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.486060232
+0000 UTC
docs/kubectl_log.md
View file @
e079e23e
...
@@ -62,4 +62,4 @@ $ kubectl log -f 123456-7890 ruby-container
...
@@ -62,4 +62,4 @@ $ kubectl log -f 123456-7890 ruby-container
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.389728881
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.484139739
+0000 UTC
docs/kubectl_namespace.md
View file @
e079e23e
...
@@ -53,4 +53,4 @@ kubectl namespace [namespace]
...
@@ -53,4 +53,4 @@ kubectl namespace [namespace]
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.389609191
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.483937463
+0000 UTC
docs/kubectl_port-forward.md
View file @
e079e23e
...
@@ -68,4 +68,4 @@ $ kubectl port-forward -p mypod 0:5000
...
@@ -68,4 +68,4 @@ $ kubectl port-forward -p mypod 0:5000
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.390241417
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.484899751
+0000 UTC
docs/kubectl_proxy.md
View file @
e079e23e
...
@@ -65,4 +65,4 @@ $ kubectl proxy --api-prefix=k8s-api
...
@@ -65,4 +65,4 @@ $ kubectl proxy --api-prefix=k8s-api
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.390360738
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.485099157
+0000 UTC
docs/kubectl_resize.md
View file @
e079e23e
...
@@ -68,4 +68,4 @@ $ kubectl resize --current-replicas=2 --replicas=3 replicationcontrollers foo
...
@@ -68,4 +68,4 @@ $ kubectl resize --current-replicas=2 --replicas=3 replicationcontrollers foo
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.389989377
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.484493463
+0000 UTC
docs/kubectl_rolling-update.md
View file @
e079e23e
...
@@ -68,4 +68,4 @@ $ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f -
...
@@ -68,4 +68,4 @@ $ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f -
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.38985117
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.484316119
+0000 UTC
docs/kubectl_run-container.md
View file @
e079e23e
...
@@ -78,4 +78,4 @@ $ kubectl run-container nginx --image=nginx --overrides='{ "apiVersion": "v1beta
...
@@ -78,4 +78,4 @@ $ kubectl run-container nginx --image=nginx --overrides='{ "apiVersion": "v1beta
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.390501802
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.485362986
+0000 UTC
docs/kubectl_stop.md
View file @
e079e23e
...
@@ -72,4 +72,4 @@ $ kubectl stop -f path/to/resources
...
@@ -72,4 +72,4 @@ $ kubectl stop -f path/to/resources
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.390631789
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.48555328
+0000 UTC
docs/kubectl_update.md
View file @
e079e23e
...
@@ -67,4 +67,4 @@ $ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState":
...
@@ -67,4 +67,4 @@ $ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState":
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.388743178
+0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.483572524
+0000 UTC
docs/kubectl_version.md
View file @
e079e23e
...
@@ -51,4 +51,4 @@ kubectl version
...
@@ -51,4 +51,4 @@ kubectl version
### SEE ALSO
### SEE ALSO
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
*
[
kubectl
](
kubectl.md
)
- kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra at 2015-04-1
6 17:04:37.39239540
8 +0000 UTC
###### Auto generated by spf13/cobra at 2015-04-1
7 18:59:11.48869251
8 +0000 UTC
docs/man/man1/kubectl-get.1
View file @
e079e23e
...
@@ -17,7 +17,7 @@ Display one or many resources.
...
@@ -17,7 +17,7 @@ Display one or many resources.
.PP
.PP
Possible resources include pods (po), replication controllers (rc), services
Possible resources include pods (po), replication controllers (rc), services
(svc), minions (mi),
or events (ev
).
(svc), minions (mi),
events (ev), or component statuses (cs
).
.PP
.PP
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
...
...
pkg/api/meta/restmapper.go
View file @
e079e23e
...
@@ -138,13 +138,17 @@ func kindToResource(kind string, mixedCase bool) (plural, singular string) {
...
@@ -138,13 +138,17 @@ func kindToResource(kind string, mixedCase bool) (plural, singular string) {
}
else
{
}
else
{
singular
=
strings
.
ToLower
(
kind
)
singular
=
strings
.
ToLower
(
kind
)
}
}
switch
string
(
singular
[
len
(
singular
)
-
1
])
{
if
strings
.
HasSuffix
(
singular
,
"status"
)
{
case
"s"
:
plural
=
strings
.
TrimSuffix
(
singular
,
"status"
)
+
"statuses"
plural
=
singular
}
else
{
case
"y"
:
switch
string
(
singular
[
len
(
singular
)
-
1
])
{
plural
=
strings
.
TrimSuffix
(
singular
,
"y"
)
+
"ies"
case
"s"
:
default
:
plural
=
singular
plural
=
singular
+
"s"
case
"y"
:
plural
=
strings
.
TrimSuffix
(
singular
,
"y"
)
+
"ies"
default
:
plural
=
singular
+
"s"
}
}
}
return
return
}
}
...
@@ -215,7 +219,7 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
...
@@ -215,7 +219,7 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
return
nil
,
fmt
.
Errorf
(
"the provided version %q has no relevant versions"
,
version
)
return
nil
,
fmt
.
Errorf
(
"the provided version %q has no relevant versions"
,
version
)
}
}
ret
urn
&
RESTMapping
{
ret
Val
:=
&
RESTMapping
{
Resource
:
resource
,
Resource
:
resource
,
APIVersion
:
version
,
APIVersion
:
version
,
Kind
:
kind
,
Kind
:
kind
,
...
@@ -224,7 +228,9 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
...
@@ -224,7 +228,9 @@ func (m *DefaultRESTMapper) RESTMapping(kind string, versions ...string) (*RESTM
Codec
:
interfaces
.
Codec
,
Codec
:
interfaces
.
Codec
,
ObjectConvertor
:
interfaces
.
ObjectConvertor
,
ObjectConvertor
:
interfaces
.
ObjectConvertor
,
MetadataAccessor
:
interfaces
.
MetadataAccessor
,
MetadataAccessor
:
interfaces
.
MetadataAccessor
,
},
nil
}
return
retVal
,
nil
}
}
// aliasToResource is used for mapping aliases to resources
// aliasToResource is used for mapping aliases to resources
...
...
pkg/api/register.go
View file @
e079e23e
...
@@ -60,6 +60,8 @@ func init() {
...
@@ -60,6 +60,8 @@ func init() {
&
PodLogOptions
{},
&
PodLogOptions
{},
&
PodExecOptions
{},
&
PodExecOptions
{},
&
PodProxyOptions
{},
&
PodProxyOptions
{},
&
ComponentStatus
{},
&
ComponentStatusList
{},
)
)
// Legacy names are supported
// Legacy names are supported
Scheme
.
AddKnownTypeWithName
(
""
,
"Minion"
,
&
Node
{})
Scheme
.
AddKnownTypeWithName
(
""
,
"Minion"
,
&
Node
{})
...
@@ -101,3 +103,5 @@ func (*ListOptions) IsAnAPIObject() {}
...
@@ -101,3 +103,5 @@ func (*ListOptions) IsAnAPIObject() {}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatus
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatusList
)
IsAnAPIObject
()
{}
pkg/api/types.go
View file @
e079e23e
...
@@ -1827,3 +1827,34 @@ func AddToNodeAddresses(addresses *[]NodeAddress, addAddresses ...NodeAddress) {
...
@@ -1827,3 +1827,34 @@ func AddToNodeAddresses(addresses *[]NodeAddress, addAddresses ...NodeAddress) {
}
}
}
}
}
}
// Type and constants for component health validation.
type
ComponentConditionType
string
// These are the valid conditions for the component.
const
(
ComponentHealthy
ComponentConditionType
=
"Healthy"
)
type
ComponentCondition
struct
{
Type
ComponentConditionType
`json:"type" description:"the type of condition"`
Status
ConditionStatus
`json:"status" description:"the status of this condition"`
Message
string
`json:"message,omitempty" description:"health check message received from the component"`
Error
string
`json:"error,omitempty" description:"error code from health check attempt (if any)"`
}
// ComponentStatus (and ComponentStatusList) holds the cluster validation info.
type
ComponentStatus
struct
{
TypeMeta
`json:",inline"`
ObjectMeta
`json:"metadata,omitempty"`
Name
string
`json:"name,omitempty" description:"name of the component"`
Conditions
[]
ComponentCondition
`json:"conditions,omitempty" description:"list of component condition objects"`
}
type
ComponentStatusList
struct
{
TypeMeta
`json:",inline"`
ListMeta
`json:"metadata,omitempty"`
Items
[]
ComponentStatus
`json:"items" description:"items is a list of component status objects"`
}
pkg/api/v1beta1/register.go
View file @
e079e23e
...
@@ -68,6 +68,8 @@ func init() {
...
@@ -68,6 +68,8 @@ func init() {
&
PodLogOptions
{},
&
PodLogOptions
{},
&
PodExecOptions
{},
&
PodExecOptions
{},
&
PodProxyOptions
{},
&
PodProxyOptions
{},
&
ComponentStatus
{},
&
ComponentStatusList
{},
)
)
// Future names are supported
// Future names are supported
api
.
Scheme
.
AddKnownTypeWithName
(
"v1beta1"
,
"Node"
,
&
Minion
{})
api
.
Scheme
.
AddKnownTypeWithName
(
"v1beta1"
,
"Node"
,
&
Minion
{})
...
@@ -110,3 +112,5 @@ func (*ListOptions) IsAnAPIObject() {}
...
@@ -110,3 +112,5 @@ func (*ListOptions) IsAnAPIObject() {}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatus
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatusList
)
IsAnAPIObject
()
{}
pkg/api/v1beta1/types.go
View file @
e079e23e
...
@@ -1592,3 +1592,32 @@ type GlusterfsVolumeSource struct {
...
@@ -1592,3 +1592,32 @@ type GlusterfsVolumeSource struct {
// the Glusterfs volume to be mounted with read-only permissions
// the Glusterfs volume to be mounted with read-only permissions
ReadOnly
bool
`json:"readOnly,omitempty" description:"Glusterfs volume to be mounted with read-only permissions"`
ReadOnly
bool
`json:"readOnly,omitempty" description:"Glusterfs volume to be mounted with read-only permissions"`
}
}
// Type and constants for component health validation.
type
ComponentConditionType
string
// These are the valid conditions for the component.
const
(
ComponentHealthy
ComponentConditionType
=
"Healthy"
)
type
ComponentCondition
struct
{
Type
ComponentConditionType
`json:"type"`
Status
ConditionStatus
`json:"status"`
Message
string
`json:"message,omitempty" description:"health check message received from the component"`
Error
string
`json:"error,omitempty" description:"error code from health check attempt (if any)"`
}
// ComponentStatus (and ComponentStatusList) holds the cluster validation info.
type
ComponentStatus
struct
{
TypeMeta
`json:",inline"`
Name
string
`json:"name,omitempty" description:"name of the component"`
Conditions
[]
ComponentCondition
`json:"conditions,omitempty"`
}
type
ComponentStatusList
struct
{
TypeMeta
`json:",inline"`
Items
[]
ComponentStatus
`json:"items" description:"items is a list of component status objects"`
}
pkg/api/v1beta2/register.go
View file @
e079e23e
...
@@ -68,6 +68,8 @@ func init() {
...
@@ -68,6 +68,8 @@ func init() {
&
PodLogOptions
{},
&
PodLogOptions
{},
&
PodExecOptions
{},
&
PodExecOptions
{},
&
PodProxyOptions
{},
&
PodProxyOptions
{},
&
ComponentStatus
{},
&
ComponentStatusList
{},
)
)
// Future names are supported
// Future names are supported
api
.
Scheme
.
AddKnownTypeWithName
(
"v1beta2"
,
"Node"
,
&
Minion
{})
api
.
Scheme
.
AddKnownTypeWithName
(
"v1beta2"
,
"Node"
,
&
Minion
{})
...
@@ -110,3 +112,5 @@ func (*ListOptions) IsAnAPIObject() {}
...
@@ -110,3 +112,5 @@ func (*ListOptions) IsAnAPIObject() {}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatus
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatusList
)
IsAnAPIObject
()
{}
pkg/api/v1beta2/types.go
View file @
e079e23e
...
@@ -1655,3 +1655,32 @@ type SecretList struct {
...
@@ -1655,3 +1655,32 @@ type SecretList struct {
Items
[]
Secret
`json:"items" description:"items is a list of secret objects"`
Items
[]
Secret
`json:"items" description:"items is a list of secret objects"`
}
}
// Type and constants for component health validation.
type
ComponentConditionType
string
// These are the valid conditions for the component.
const
(
ComponentHealthy
ComponentConditionType
=
"Healthy"
)
type
ComponentCondition
struct
{
Type
ComponentConditionType
`json:"type"`
Status
ConditionStatus
`json:"status"`
Message
string
`json:"message,omitempty" description:"health check message received from the component"`
Error
string
`json:"error,omitempty" description:"error code from health check attempt (if any)"`
}
// ComponentStatus (and ComponentStatusList) holds the cluster validation info.
type
ComponentStatus
struct
{
TypeMeta
`json:",inline"`
Name
string
`json:"name,omitempty" description:"name of the component"`
Conditions
[]
ComponentCondition
`json:"conditions,omitempty"`
}
type
ComponentStatusList
struct
{
TypeMeta
`json:",inline"`
Items
[]
ComponentStatus
`json:"items" description:"items is a list of component status objects"`
}
pkg/api/v1beta3/register.go
View file @
e079e23e
...
@@ -61,6 +61,8 @@ func init() {
...
@@ -61,6 +61,8 @@ func init() {
&
PodLogOptions
{},
&
PodLogOptions
{},
&
PodExecOptions
{},
&
PodExecOptions
{},
&
PodProxyOptions
{},
&
PodProxyOptions
{},
&
ComponentStatus
{},
&
ComponentStatusList
{},
)
)
// Legacy names are supported
// Legacy names are supported
api
.
Scheme
.
AddKnownTypeWithName
(
"v1beta3"
,
"Minion"
,
&
Node
{})
api
.
Scheme
.
AddKnownTypeWithName
(
"v1beta3"
,
"Minion"
,
&
Node
{})
...
@@ -102,3 +104,5 @@ func (*ListOptions) IsAnAPIObject() {}
...
@@ -102,3 +104,5 @@ func (*ListOptions) IsAnAPIObject() {}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodLogOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodExecOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
PodProxyOptions
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatus
)
IsAnAPIObject
()
{}
func
(
*
ComponentStatusList
)
IsAnAPIObject
()
{}
pkg/api/v1beta3/types.go
View file @
e079e23e
...
@@ -1672,3 +1672,34 @@ type SecretList struct {
...
@@ -1672,3 +1672,34 @@ type SecretList struct {
Items
[]
Secret
`json:"items" description:"items is a list of secret objects"`
Items
[]
Secret
`json:"items" description:"items is a list of secret objects"`
}
}
// Type and constants for component health validation.
type
ComponentConditionType
string
// These are the valid conditions for the component.
const
(
ComponentHealthy
ComponentConditionType
=
"Healthy"
)
type
ComponentCondition
struct
{
Type
ComponentConditionType
`json:"type" description:"type of component condition, currently only Healthy"`
Status
ConditionStatus
`json:"status" description:"current status of this component condition"`
Message
string
`json:"message,omitempty" description:"health check message received from the component"`
Error
string
`json:"error,omitempty" description:"error code from health check attempt (if any)"`
}
// ComponentStatus (and ComponentStatusList) holds the cluster validation info.
type
ComponentStatus
struct
{
TypeMeta
`json:",inline"`
ObjectMeta
`json:"metadata,omitempty"`
Name
string
`json:"name,omitempty" description:"name of the component"`
Conditions
[]
ComponentCondition
`json:"conditions,omitempty" description:"Conditions is a list of ComponentCondition objects"`
}
type
ComponentStatusList
struct
{
TypeMeta
`json:",inline"`
ListMeta
`json:"metadata,omitempty"`
Items
[]
ComponentStatus
`json:"items" description:"items is a list of ComponentStatus objects"`
}
pkg/apiserver/apiserver.go
View file @
e079e23e
...
@@ -140,7 +140,8 @@ func (g *APIGroupVersion) InstallREST(container *restful.Container) error {
...
@@ -140,7 +140,8 @@ func (g *APIGroupVersion) InstallREST(container *restful.Container) error {
return
errors
.
NewAggregate
(
registrationErrors
)
return
errors
.
NewAggregate
(
registrationErrors
)
}
}
// TODO: Convert to go-restful
// TODO: This endpoint is deprecated and should be removed at some point.
// Use "componentstatus" API instead.
func
InstallValidator
(
mux
Mux
,
servers
func
()
map
[
string
]
Server
)
{
func
InstallValidator
(
mux
Mux
,
servers
func
()
map
[
string
]
Server
)
{
mux
.
Handle
(
"/validate"
,
NewValidator
(
servers
))
mux
.
Handle
(
"/validate"
,
NewValidator
(
servers
))
}
}
...
...
pkg/apiserver/validator.go
View file @
e079e23e
...
@@ -48,13 +48,39 @@ type validator struct {
...
@@ -48,13 +48,39 @@ type validator struct {
rt
http
.
RoundTripper
rt
http
.
RoundTripper
}
}
type
ServerStatus
struct
{
Component
string
`json:"component,omitempty"`
Health
string
`json:"health,omitempty"`
HealthCode
probe
.
Result
`json:"healthCode,omitempty"`
Msg
string
`json:"msg,omitempty"`
Err
string
`json:"err,omitempty"`
}
// TODO: can this use pkg/probe/http
// TODO: can this use pkg/probe/http
func
(
s
*
Server
)
check
(
client
httpGet
)
(
probe
.
Result
,
string
,
error
)
{
func
(
server
*
Server
)
DoServerCheck
(
rt
http
.
RoundTripper
)
(
probe
.
Result
,
string
,
error
)
{
var
client
*
http
.
Client
scheme
:=
"http://"
scheme
:=
"http://"
if
s
.
EnableHTTPS
{
if
server
.
EnableHTTPS
{
// TODO(roberthbailey): The servers that use HTTPS are currently the
// kubelets, and we should be using a standard kubelet client library
// to talk to them rather than a separate http client.
transport
:=
&
http
.
Transport
{
Proxy
:
http
.
ProxyFromEnvironment
,
Dial
:
(
&
net
.
Dialer
{
Timeout
:
30
*
time
.
Second
,
KeepAlive
:
30
*
time
.
Second
,
})
.
Dial
,
TLSHandshakeTimeout
:
10
*
time
.
Second
,
TLSClientConfig
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
}
client
=
&
http
.
Client
{
Transport
:
transport
}
scheme
=
"https://"
scheme
=
"https://"
}
else
{
client
=
&
http
.
Client
{
Transport
:
rt
}
}
}
resp
,
err
:=
client
.
Get
(
scheme
+
net
.
JoinHostPort
(
s
.
Addr
,
strconv
.
Itoa
(
s
.
Port
))
+
s
.
Path
)
resp
,
err
:=
client
.
Get
(
scheme
+
net
.
JoinHostPort
(
server
.
Addr
,
strconv
.
Itoa
(
server
.
Port
))
+
server
.
Path
)
if
err
!=
nil
{
if
err
!=
nil
{
return
probe
.
Unknown
,
""
,
err
return
probe
.
Unknown
,
""
,
err
}
}
...
@@ -70,14 +96,6 @@ func (s *Server) check(client httpGet) (probe.Result, string, error) {
...
@@ -70,14 +96,6 @@ func (s *Server) check(client httpGet) (probe.Result, string, error) {
return
probe
.
Success
,
string
(
data
),
nil
return
probe
.
Success
,
string
(
data
),
nil
}
}
type
ServerStatus
struct
{
Component
string
`json:"component,omitempty"`
Health
string
`json:"health,omitempty"`
HealthCode
probe
.
Result
`json:"healthCode,omitempty"`
Msg
string
`json:"msg,omitempty"`
Err
string
`json:"err,omitempty"`
}
func
(
v
*
validator
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
v
*
validator
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
verb
:=
"get"
verb
:=
"get"
apiResource
:=
""
apiResource
:=
""
...
@@ -88,21 +106,7 @@ func (v *validator) ServeHTTP(w http.ResponseWriter, r *http.Request) {
...
@@ -88,21 +106,7 @@ func (v *validator) ServeHTTP(w http.ResponseWriter, r *http.Request) {
reply
:=
[]
ServerStatus
{}
reply
:=
[]
ServerStatus
{}
for
name
,
server
:=
range
v
.
servers
()
{
for
name
,
server
:=
range
v
.
servers
()
{
transport
:=
v
.
rt
transport
:=
v
.
rt
if
server
.
EnableHTTPS
{
status
,
msg
,
err
:=
server
.
DoServerCheck
(
transport
)
// TODO(roberthbailey): The servers that use HTTPS are currently the
// kubelets, and we should be using a standard kubelet client library
// to talk to them rather than a separate http client.
transport
=
&
http
.
Transport
{
Proxy
:
http
.
ProxyFromEnvironment
,
Dial
:
(
&
net
.
Dialer
{
Timeout
:
30
*
time
.
Second
,
KeepAlive
:
30
*
time
.
Second
,
})
.
Dial
,
TLSHandshakeTimeout
:
10
*
time
.
Second
,
TLSClientConfig
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
}
}
status
,
msg
,
err
:=
server
.
check
(
&
http
.
Client
{
Transport
:
transport
})
var
errorMsg
string
var
errorMsg
string
if
err
!=
nil
{
if
err
!=
nil
{
errorMsg
=
err
.
Error
()
errorMsg
=
err
.
Error
()
...
...
pkg/apiserver/validator_test.go
View file @
e079e23e
...
@@ -65,8 +65,7 @@ func TestValidate(t *testing.T) {
...
@@ -65,8 +65,7 @@ func TestValidate(t *testing.T) {
StatusCode
:
test
.
code
,
StatusCode
:
test
.
code
,
},
},
}
}
fake
:=
&
http
.
Client
{
Transport
:
fakeRT
}
status
,
data
,
err
:=
s
.
DoServerCheck
(
fakeRT
)
status
,
data
,
err
:=
s
.
check
(
fake
)
expect
:=
fmt
.
Sprintf
(
"http://%s:%d/healthz"
,
s
.
Addr
,
s
.
Port
)
expect
:=
fmt
.
Sprintf
(
"http://%s:%d/healthz"
,
s
.
Addr
,
s
.
Port
)
if
fakeRT
.
url
!=
expect
{
if
fakeRT
.
url
!=
expect
{
t
.
Errorf
(
"expected %s, got %s"
,
expect
,
fakeRT
.
url
)
t
.
Errorf
(
"expected %s, got %s"
,
expect
,
fakeRT
.
url
)
...
...
pkg/client/client.go
View file @
e079e23e
...
@@ -43,6 +43,7 @@ type Interface interface {
...
@@ -43,6 +43,7 @@ type Interface interface {
NamespacesInterface
NamespacesInterface
PersistentVolumesInterface
PersistentVolumesInterface
PersistentVolumeClaimsNamespacer
PersistentVolumeClaimsNamespacer
ComponentStatusesInterface
}
}
func
(
c
*
Client
)
ReplicationControllers
(
namespace
string
)
ReplicationControllerInterface
{
func
(
c
*
Client
)
ReplicationControllers
(
namespace
string
)
ReplicationControllerInterface
{
...
@@ -92,6 +93,10 @@ func (c *Client) PersistentVolumeClaims(namespace string) PersistentVolumeClaimI
...
@@ -92,6 +93,10 @@ func (c *Client) PersistentVolumeClaims(namespace string) PersistentVolumeClaimI
return
newPersistentVolumeClaims
(
c
,
namespace
)
return
newPersistentVolumeClaims
(
c
,
namespace
)
}
}
func
(
c
*
Client
)
ComponentStatuses
()
ComponentStatusInterface
{
return
newComponentStatuses
(
c
)
}
// VersionInterface has a method to retrieve the server version.
// VersionInterface has a method to retrieve the server version.
type
VersionInterface
interface
{
type
VersionInterface
interface
{
ServerVersion
()
(
*
version
.
Info
,
error
)
ServerVersion
()
(
*
version
.
Info
,
error
)
...
@@ -137,6 +142,25 @@ func (c *Client) ServerAPIVersions() (*api.APIVersions, error) {
...
@@ -137,6 +142,25 @@ func (c *Client) ServerAPIVersions() (*api.APIVersions, error) {
return
&
v
,
nil
return
&
v
,
nil
}
}
type
ComponentValidatorInterface
interface
{
ValidateComponents
()
(
*
api
.
ComponentStatusList
,
error
)
}
// ValidateComponents retrieves and parses the master's self-monitored cluster state.
// TODO: This should hit the versioned endpoint when that is implemented.
func
(
c
*
Client
)
ValidateComponents
()
(
*
api
.
ComponentStatusList
,
error
)
{
body
,
err
:=
c
.
Get
()
.
AbsPath
(
"/validate"
)
.
DoRaw
()
if
err
!=
nil
{
return
nil
,
err
}
statuses
:=
[]
api
.
ComponentStatus
{}
if
err
:=
json
.
Unmarshal
(
body
,
&
statuses
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"got '%s': %v"
,
string
(
body
),
err
)
}
return
&
api
.
ComponentStatusList
{
Items
:
statuses
},
nil
}
// IsTimeout tests if this is a timeout error in the underlying transport.
// IsTimeout tests if this is a timeout error in the underlying transport.
// This is unbelievably ugly.
// This is unbelievably ugly.
// See: http://stackoverflow.com/questions/23494950/specifically-check-for-timeout-error for details
// See: http://stackoverflow.com/questions/23494950/specifically-check-for-timeout-error for details
...
...
pkg/client/componentstatuses.go
0 → 100644
View file @
e079e23e
/*
Copyright 2015 Google Inc. 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
client
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
)
type
ComponentStatusesInterface
interface
{
ComponentStatuses
()
ComponentStatusInterface
}
// ComponentStatusInterface contains methods to retrieve ComponentStatus
type
ComponentStatusInterface
interface
{
List
(
label
labels
.
Selector
,
field
fields
.
Selector
)
(
*
api
.
ComponentStatusList
,
error
)
Get
(
name
string
)
(
*
api
.
ComponentStatus
,
error
)
// TODO: It'd be nice to have watch support at some point
//Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
}
// componentStatuses implements ComponentStatusesInterface
type
componentStatuses
struct
{
client
*
Client
}
func
newComponentStatuses
(
c
*
Client
)
*
componentStatuses
{
return
&
componentStatuses
{
c
}
}
func
(
c
*
componentStatuses
)
List
(
label
labels
.
Selector
,
field
fields
.
Selector
)
(
result
*
api
.
ComponentStatusList
,
err
error
)
{
result
=
&
api
.
ComponentStatusList
{}
err
=
c
.
client
.
Get
()
.
Resource
(
"componentStatuses"
)
.
LabelsSelectorParam
(
label
)
.
FieldsSelectorParam
(
field
)
.
Do
()
.
Into
(
result
)
return
result
,
err
}
func
(
c
*
componentStatuses
)
Get
(
name
string
)
(
result
*
api
.
ComponentStatus
,
err
error
)
{
result
=
&
api
.
ComponentStatus
{}
err
=
c
.
client
.
Get
()
.
Resource
(
"componentStatuses"
)
.
Name
(
name
)
.
Do
()
.
Into
(
result
)
return
}
pkg/client/testclient/fake_componentstatuses.go
0 → 100644
View file @
e079e23e
/*
Copyright 2015 Google Inc. 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
testclient
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
)
// Fake implements ComponentStatusInterface.
type
FakeComponentStatuses
struct
{
Fake
*
Fake
}
func
(
c
*
FakeComponentStatuses
)
List
(
label
labels
.
Selector
,
field
fields
.
Selector
)
(
result
*
api
.
ComponentStatusList
,
err
error
)
{
obj
,
err
:=
c
.
Fake
.
Invokes
(
FakeAction
{
Action
:
"list-componentstatuses"
},
&
api
.
ComponentStatusList
{})
return
obj
.
(
*
api
.
ComponentStatusList
),
err
}
func
(
c
*
FakeComponentStatuses
)
Get
(
name
string
)
(
*
api
.
ComponentStatus
,
error
)
{
obj
,
err
:=
c
.
Fake
.
Invokes
(
FakeAction
{
Action
:
"get-componentstatus"
,
Value
:
name
},
&
api
.
ComponentStatus
{})
// c.Actions = append(c.Actions, FakeAction{Action: "get-componentstatuses", Value: nil})
// testStatus := &api.ComponentStatus{
// Name: "test",
// Health: "ok",
// HealthCode: int(probe.Success),
// Message: "ok",
// Error: "",
// }
// return &api.ComponentStatusList{Items: []api.ComponentStatus{*testStatus}}, nil
return
obj
.
(
*
api
.
ComponentStatus
),
err
}
pkg/client/testclient/testclient.go
View file @
e079e23e
...
@@ -125,3 +125,7 @@ func (c *Fake) ServerAPIVersions() (*api.APIVersions, error) {
...
@@ -125,3 +125,7 @@ func (c *Fake) ServerAPIVersions() (*api.APIVersions, error) {
c
.
Actions
=
append
(
c
.
Actions
,
FakeAction
{
Action
:
"get-apiversions"
,
Value
:
nil
})
c
.
Actions
=
append
(
c
.
Actions
,
FakeAction
{
Action
:
"get-apiversions"
,
Value
:
nil
})
return
&
api
.
APIVersions
{
Versions
:
[]
string
{
"v1beta1"
,
"v1beta2"
}},
nil
return
&
api
.
APIVersions
{
Versions
:
[]
string
{
"v1beta1"
,
"v1beta2"
}},
nil
}
}
func
(
c
*
Fake
)
ComponentStatuses
()
client
.
ComponentStatusInterface
{
return
&
FakeComponentStatuses
{
Fake
:
c
}
}
pkg/kubectl/cmd/cmd_test.go
View file @
e079e23e
...
@@ -150,6 +150,13 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
...
@@ -150,6 +150,13 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
Object
:
func
()
(
meta
.
RESTMapper
,
runtime
.
ObjectTyper
)
{
return
latest
.
RESTMapper
,
api
.
Scheme
return
latest
.
RESTMapper
,
api
.
Scheme
},
},
Client
:
func
()
(
*
client
.
Client
,
error
)
{
// Swap out the HTTP client out of the client with the fake's version.
fakeClient
:=
t
.
Client
.
(
*
client
.
FakeRESTClient
)
c
:=
client
.
NewOrDie
(
t
.
ClientConfig
)
c
.
Client
=
fakeClient
.
Client
return
c
,
t
.
Err
},
RESTClient
:
func
(
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
RESTClient
:
func
(
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
return
t
.
Client
,
t
.
Err
return
t
.
Client
,
t
.
Err
},
},
...
...
pkg/kubectl/cmd/get.go
View file @
e079e23e
...
@@ -34,7 +34,7 @@ const (
...
@@ -34,7 +34,7 @@ const (
get_long
=
`Display one or many resources.
get_long
=
`Display one or many resources.
Possible resources include pods (po), replication controllers (rc), services
Possible resources include pods (po), replication controllers (rc), services
(svc), minions (mi),
or events (ev
).
(svc), minions (mi),
events (ev), or component statuses (cs
).
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).`
...
...
pkg/kubectl/cmd/get_test.go
View file @
e079e23e
...
@@ -87,6 +87,31 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
...
@@ -87,6 +87,31 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
return
pods
,
svc
,
rc
return
pods
,
svc
,
rc
}
}
func
testComponentStatusData
()
*
api
.
ComponentStatusList
{
good
:=
&
api
.
ComponentStatus
{
Name
:
"servergood"
,
Conditions
:
[]
api
.
ComponentCondition
{
{
Type
:
api
.
ComponentHealthy
,
Status
:
api
.
ConditionTrue
,
Message
:
"ok"
,
Error
:
"nil"
},
},
}
bad
:=
&
api
.
ComponentStatus
{
Name
:
"serverbad"
,
Conditions
:
[]
api
.
ComponentCondition
{
{
Type
:
api
.
ComponentHealthy
,
Status
:
api
.
ConditionFalse
,
Message
:
""
,
Error
:
"bad status: 500"
},
},
}
unknown
:=
&
api
.
ComponentStatus
{
Name
:
"serverunknown"
,
Conditions
:
[]
api
.
ComponentCondition
{
{
Type
:
api
.
ComponentHealthy
,
Status
:
api
.
ConditionUnknown
,
Message
:
""
,
Error
:
"fizzbuzz error"
},
},
}
return
&
api
.
ComponentStatusList
{
Items
:
[]
api
.
ComponentStatus
{
*
good
,
*
bad
,
*
unknown
},
}
}
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func
TestGetUnknownSchemaObject
(
t
*
testing
.
T
)
{
func
TestGetUnknownSchemaObject
(
t
*
testing
.
T
)
{
f
,
tf
,
codec
:=
NewTestFactory
()
f
,
tf
,
codec
:=
NewTestFactory
()
...
@@ -188,6 +213,32 @@ func TestGetListObjects(t *testing.T) {
...
@@ -188,6 +213,32 @@ func TestGetListObjects(t *testing.T) {
}
}
}
}
func
TestGetListComponentStatus
(
t
*
testing
.
T
)
{
statuses
:=
testComponentStatusData
()
f
,
tf
,
codec
:=
NewAPIFactory
()
tf
.
Printer
=
&
testPrinter
{}
tf
.
Client
=
&
client
.
FakeRESTClient
{
Codec
:
codec
,
Resp
:
&
http
.
Response
{
StatusCode
:
200
,
Body
:
objBody
(
codec
,
statuses
)},
}
tf
.
Namespace
=
"test"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
NewCmdGet
(
f
,
buf
)
cmd
.
SetOutput
(
buf
)
cmd
.
Run
(
cmd
,
[]
string
{
"componentstatuses"
})
expected
:=
[]
runtime
.
Object
{
statuses
}
actual
:=
tf
.
Printer
.
(
*
testPrinter
)
.
Objects
if
!
reflect
.
DeepEqual
(
expected
,
actual
)
{
t
.
Errorf
(
"unexpected object: %#v %#v"
,
expected
,
actual
)
}
if
len
(
buf
.
String
())
==
0
{
t
.
Errorf
(
"unexpected empty output"
)
}
}
func
TestGetMultipleTypeObjects
(
t
*
testing
.
T
)
{
func
TestGetMultipleTypeObjects
(
t
*
testing
.
T
)
{
pods
,
svc
,
_
:=
testData
()
pods
,
svc
,
_
:=
testData
()
...
...
pkg/kubectl/kubectl.go
View file @
e079e23e
...
@@ -96,17 +96,19 @@ func (e ShortcutExpander) VersionAndKindForResource(resource string) (defaultVer
...
@@ -96,17 +96,19 @@ func (e ShortcutExpander) VersionAndKindForResource(resource string) (defaultVer
// indeed a shortcut. Otherwise, will return resource unmodified.
// indeed a shortcut. Otherwise, will return resource unmodified.
func
expandResourceShortcut
(
resource
string
)
string
{
func
expandResourceShortcut
(
resource
string
)
string
{
shortForms
:=
map
[
string
]
string
{
shortForms
:=
map
[
string
]
string
{
"po"
:
"pods"
,
// Please keep this alphabetized
"rc"
:
"replicationcontrollers"
,
"cs"
:
"componentstatus"
,
// DEPRECATED: will be removed before 1.0
"se"
:
"services"
,
"svc"
:
"services"
,
"mi"
:
"minions"
,
"ev"
:
"events"
,
"ev"
:
"events"
,
"limits"
:
"limitRanges"
,
"limits"
:
"limitRanges"
,
"quota"
:
"resourceQuotas"
,
"mi"
:
"minions"
,
"po"
:
"pods"
,
"pv"
:
"persistentVolumes"
,
"pv"
:
"persistentVolumes"
,
"pvc"
:
"persistentVolumeClaims"
,
"pvc"
:
"persistentVolumeClaims"
,
"quota"
:
"resourceQuotas"
,
"rc"
:
"replicationcontrollers"
,
// DEPRECATED: will be removed before 1.0
"se"
:
"services"
,
"svc"
:
"services"
,
}
}
if
expanded
,
ok
:=
shortForms
[
resource
];
ok
{
if
expanded
,
ok
:=
shortForms
[
resource
];
ok
{
return
expanded
return
expanded
...
...
pkg/kubectl/resource_printer.go
View file @
e079e23e
...
@@ -256,6 +256,7 @@ var namespaceColumns = []string{"NAME", "LABELS", "STATUS"}
...
@@ -256,6 +256,7 @@ var namespaceColumns = []string{"NAME", "LABELS", "STATUS"}
var
secretColumns
=
[]
string
{
"NAME"
,
"DATA"
}
var
secretColumns
=
[]
string
{
"NAME"
,
"DATA"
}
var
persistentVolumeColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"CAPACITY"
,
"ACCESSMODES"
,
"STATUS"
,
"CLAIM"
}
var
persistentVolumeColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"CAPACITY"
,
"ACCESSMODES"
,
"STATUS"
,
"CLAIM"
}
var
persistentVolumeClaimColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"STATUS"
,
"VOLUME"
}
var
persistentVolumeClaimColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"STATUS"
,
"VOLUME"
}
var
componentStatusColumns
=
[]
string
{
"NAME"
,
"STATUS"
,
"MESSAGE"
,
"ERROR"
}
// addDefaultHandlers adds print handlers for default Kubernetes types.
// addDefaultHandlers adds print handlers for default Kubernetes types.
func
(
h
*
HumanReadablePrinter
)
addDefaultHandlers
()
{
func
(
h
*
HumanReadablePrinter
)
addDefaultHandlers
()
{
...
@@ -284,6 +285,8 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
...
@@ -284,6 +285,8 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
h
.
Handler
(
persistentVolumeClaimColumns
,
printPersistentVolumeClaimList
)
h
.
Handler
(
persistentVolumeClaimColumns
,
printPersistentVolumeClaimList
)
h
.
Handler
(
persistentVolumeColumns
,
printPersistentVolume
)
h
.
Handler
(
persistentVolumeColumns
,
printPersistentVolume
)
h
.
Handler
(
persistentVolumeColumns
,
printPersistentVolumeList
)
h
.
Handler
(
persistentVolumeColumns
,
printPersistentVolumeList
)
h
.
Handler
(
componentStatusColumns
,
printComponentStatus
)
h
.
Handler
(
componentStatusColumns
,
printComponentStatusList
)
}
}
func
(
h
*
HumanReadablePrinter
)
unknown
(
data
[]
byte
,
w
io
.
Writer
)
error
{
func
(
h
*
HumanReadablePrinter
)
unknown
(
data
[]
byte
,
w
io
.
Writer
)
error
{
...
@@ -644,6 +647,36 @@ func printResourceQuotaList(list *api.ResourceQuotaList, w io.Writer) error {
...
@@ -644,6 +647,36 @@ func printResourceQuotaList(list *api.ResourceQuotaList, w io.Writer) error {
return
nil
return
nil
}
}
func
printComponentStatus
(
item
*
api
.
ComponentStatus
,
w
io
.
Writer
)
error
{
status
:=
"Unknown"
message
:=
""
error
:=
""
for
_
,
condition
:=
range
item
.
Conditions
{
if
condition
.
Type
==
api
.
ComponentHealthy
{
if
condition
.
Status
==
api
.
ConditionTrue
{
status
=
"Healthy"
}
else
{
status
=
"Unhealthy"
}
message
=
condition
.
Message
error
=
condition
.
Error
break
}
}
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%s
\t
%s
\t
%s
\n
"
,
item
.
Name
,
status
,
message
,
error
)
return
err
}
func
printComponentStatusList
(
list
*
api
.
ComponentStatusList
,
w
io
.
Writer
)
error
{
for
_
,
item
:=
range
list
.
Items
{
if
err
:=
printComponentStatus
(
&
item
,
w
);
err
!=
nil
{
return
err
}
}
return
nil
}
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
func
(
h
*
HumanReadablePrinter
)
PrintObj
(
obj
runtime
.
Object
,
output
io
.
Writer
)
error
{
func
(
h
*
HumanReadablePrinter
)
PrintObj
(
obj
runtime
.
Object
,
output
io
.
Writer
)
error
{
w
:=
tabwriter
.
NewWriter
(
output
,
10
,
4
,
3
,
' '
,
0
)
w
:=
tabwriter
.
NewWriter
(
output
,
10
,
4
,
3
,
' '
,
0
)
...
...
pkg/master/master.go
View file @
e079e23e
...
@@ -43,6 +43,7 @@ import (
...
@@ -43,6 +43,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/componentstatus"
controlleretcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/etcd"
controlleretcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint"
endpointsetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint/etcd"
endpointsetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint/etcd"
...
@@ -416,6 +417,8 @@ func (m *Master) init(c *Config) {
...
@@ -416,6 +417,8 @@ func (m *Master) init(c *Config) {
"persistentVolumes/status"
:
persistentVolumeStatusStorage
,
"persistentVolumes/status"
:
persistentVolumeStatusStorage
,
"persistentVolumeClaims"
:
persistentVolumeClaimStorage
,
"persistentVolumeClaims"
:
persistentVolumeClaimStorage
,
"persistentVolumeClaims/status"
:
persistentVolumeClaimStatusStorage
,
"persistentVolumeClaims/status"
:
persistentVolumeClaimStatusStorage
,
"componentStatuses"
:
componentstatus
.
NewStorage
(
func
()
map
[
string
]
apiserver
.
Server
{
return
m
.
getServersToValidate
(
c
)
}),
}
}
apiVersions
:=
[]
string
{
"v1beta1"
,
"v1beta2"
}
apiVersions
:=
[]
string
{
"v1beta1"
,
"v1beta2"
}
...
...
pkg/registry/componentstatus/doc.go
0 → 100644
View file @
e079e23e
/*
Copyright 2015 Google Inc. 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 componentstatus provides interfaces and implementation for retrieving cluster
// component status.
package
componentstatus
pkg/registry/componentstatus/rest.go
0 → 100644
View file @
e079e23e
/*
Copyright 2015 Google Inc. 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
componentstatus
import
(
"fmt"
"net/http"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/probe"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
type
REST
struct
{
GetServersToValidate
func
()
map
[
string
]
apiserver
.
Server
rt
http
.
RoundTripper
}
// NewStorage returns a new REST.
func
NewStorage
(
serverRetriever
func
()
map
[
string
]
apiserver
.
Server
)
*
REST
{
return
&
REST
{
GetServersToValidate
:
serverRetriever
,
rt
:
http
.
DefaultTransport
,
}
}
func
(
rs
*
REST
)
New
()
runtime
.
Object
{
return
&
api
.
ComponentStatus
{}
}
func
(
rs
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
ComponentStatusList
{}
}
// Returns the list of component status. Note that the label and field are both ignored.
// Note that this call doesn't support labels or selectors.
func
(
rs
*
REST
)
List
(
ctx
api
.
Context
,
label
labels
.
Selector
,
field
fields
.
Selector
)
(
runtime
.
Object
,
error
)
{
servers
:=
rs
.
GetServersToValidate
()
// TODO: This should be parallelized.
reply
:=
[]
api
.
ComponentStatus
{}
for
name
,
server
:=
range
servers
{
status
:=
rs
.
getComponentStatus
(
name
,
server
)
reply
=
append
(
reply
,
*
status
)
}
return
&
api
.
ComponentStatusList
{
Items
:
reply
},
nil
}
func
(
rs
*
REST
)
Get
(
ctx
api
.
Context
,
name
string
)
(
runtime
.
Object
,
error
)
{
servers
:=
rs
.
GetServersToValidate
()
if
server
,
ok
:=
servers
[
name
];
!
ok
{
return
nil
,
fmt
.
Errorf
(
"Component not found: %s"
,
name
)
}
else
{
return
rs
.
getComponentStatus
(
name
,
server
),
nil
}
}
func
ToConditionStatus
(
s
probe
.
Result
)
api
.
ConditionStatus
{
switch
s
{
case
probe
.
Success
:
return
api
.
ConditionTrue
case
probe
.
Failure
:
return
api
.
ConditionFalse
default
:
return
api
.
ConditionUnknown
}
}
func
(
rs
*
REST
)
getComponentStatus
(
name
string
,
server
apiserver
.
Server
)
*
api
.
ComponentStatus
{
transport
:=
rs
.
rt
status
,
msg
,
err
:=
server
.
DoServerCheck
(
transport
)
var
errorMsg
string
if
err
!=
nil
{
errorMsg
=
err
.
Error
()
}
else
{
errorMsg
=
"nil"
}
c
:=
&
api
.
ComponentCondition
{
Type
:
api
.
ComponentHealthy
,
Status
:
ToConditionStatus
(
status
),
Message
:
msg
,
Error
:
errorMsg
,
}
retVal
:=
&
api
.
ComponentStatus
{
Name
:
name
,
Conditions
:
[]
api
.
ComponentCondition
{
*
c
},
}
return
retVal
}
pkg/registry/componentstatus/rest_test.go
0 → 100644
View file @
e079e23e
/*
Copyright 2015 Google Inc. 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
componentstatus
import
(
"bytes"
"fmt"
"io/ioutil"
"net/http"
"reflect"
"strings"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
type
fakeRoundTripper
struct
{
err
error
resp
*
http
.
Response
url
string
}
func
(
f
*
fakeRoundTripper
)
RoundTrip
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
f
.
url
=
req
.
URL
.
String
()
return
f
.
resp
,
f
.
err
}
type
testResponse
struct
{
code
int
data
string
err
error
}
func
NewTestREST
(
resp
testResponse
)
*
REST
{
return
&
REST
{
GetServersToValidate
:
func
()
map
[
string
]
apiserver
.
Server
{
return
map
[
string
]
apiserver
.
Server
{
"test1"
:
{
Addr
:
"testserver1"
,
Port
:
8000
,
Path
:
"/healthz"
},
}
},
rt
:
&
fakeRoundTripper
{
err
:
resp
.
err
,
resp
:
&
http
.
Response
{
Body
:
ioutil
.
NopCloser
(
bytes
.
NewBufferString
(
resp
.
data
)),
StatusCode
:
resp
.
code
,
},
},
}
}
func
createTestStatus
(
name
string
,
status
api
.
ConditionStatus
,
msg
string
,
err
string
)
*
api
.
ComponentStatus
{
return
&
api
.
ComponentStatus
{
Name
:
name
,
Conditions
:
[]
api
.
ComponentCondition
{
{
Type
:
api
.
ComponentHealthy
,
Status
:
status
,
Message
:
msg
,
Error
:
err
},
},
}
}
func
TestList_NoError
(
t
*
testing
.
T
)
{
r
:=
NewTestREST
(
testResponse
{
code
:
200
,
data
:
"ok"
})
got
,
err
:=
r
.
List
(
api
.
NewContext
(),
labels
.
Everything
(),
fields
.
Everything
())
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
expect
:=
&
api
.
ComponentStatusList
{
Items
:
[]
api
.
ComponentStatus
{
*
(
createTestStatus
(
"test1"
,
api
.
ConditionTrue
,
"ok"
,
"nil"
))},
}
if
e
,
a
:=
expect
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"Got unexpected object. Diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
func
TestList_FailedCheck
(
t
*
testing
.
T
)
{
r
:=
NewTestREST
(
testResponse
{
code
:
500
,
data
:
""
})
got
,
err
:=
r
.
List
(
api
.
NewContext
(),
labels
.
Everything
(),
fields
.
Everything
())
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
expect
:=
&
api
.
ComponentStatusList
{
Items
:
[]
api
.
ComponentStatus
{
*
(
createTestStatus
(
"test1"
,
api
.
ConditionFalse
,
""
,
"unhealthy http status code: 500 ()"
))},
}
if
e
,
a
:=
expect
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"Got unexpected object. Diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
func
TestList_UnknownError
(
t
*
testing
.
T
)
{
r
:=
NewTestREST
(
testResponse
{
code
:
500
,
data
:
""
,
err
:
fmt
.
Errorf
(
"fizzbuzz error"
)})
got
,
err
:=
r
.
List
(
api
.
NewContext
(),
labels
.
Everything
(),
fields
.
Everything
())
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
expect
:=
&
api
.
ComponentStatusList
{
Items
:
[]
api
.
ComponentStatus
{
*
(
createTestStatus
(
"test1"
,
api
.
ConditionUnknown
,
""
,
"Get http://testserver1:8000/healthz: fizzbuzz error"
))},
}
if
e
,
a
:=
expect
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"Got unexpected object. Diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
func
TestGet_NoError
(
t
*
testing
.
T
)
{
r
:=
NewTestREST
(
testResponse
{
code
:
200
,
data
:
"ok"
})
got
,
err
:=
r
.
Get
(
api
.
NewContext
(),
"test1"
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
expect
:=
createTestStatus
(
"test1"
,
api
.
ConditionTrue
,
"ok"
,
"nil"
)
if
e
,
a
:=
expect
,
got
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"Got unexpected object. Diff: %s"
,
util
.
ObjectDiff
(
e
,
a
))
}
}
func
TestGet_BadName
(
t
*
testing
.
T
)
{
r
:=
NewTestREST
(
testResponse
{
code
:
200
,
data
:
"ok"
})
_
,
err
:=
r
.
Get
(
api
.
NewContext
(),
"invalidname"
)
if
err
==
nil
{
t
.
Fatalf
(
"Expected error, but did not get one"
)
}
if
!
strings
.
Contains
(
err
.
Error
(),
"Component not found: invalidname"
)
{
t
.
Fatalf
(
"Got unexpected error: %v"
,
err
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment