Merge pull request #4267 from rsokolowski/guestbook-doc

Update guestbook example to use replication controller instead of a naked pod.
This commit is contained in:
Deyuan Deng 2015-02-24 15:57:27 -05:00
commit f2698e5905
15 changed files with 315 additions and 264 deletions

View File

@ -108,12 +108,12 @@ func TestExampleObjectSchemas(t *testing.T) {
"service-list": &api.ServiceList{},
},
"../examples/guestbook": {
"frontend-controller": &api.ReplicationController{},
"redis-slave-controller": &api.ReplicationController{},
"redis-master": &api.Pod{},
"frontend-service": &api.Service{},
"redis-master-service": &api.Service{},
"redis-slave-service": &api.Service{},
"frontend-controller": &api.ReplicationController{},
"redis-slave-controller": &api.ReplicationController{},
"redis-master-controller": &api.ReplicationController{},
"frontend-service": &api.Service{},
"redis-master-service": &api.Service{},
"redis-slave-service": &api.Service{},
},
"../examples/guestbook/v1beta3": {
"frontend-controller": &api.ReplicationController{},

View File

@ -21,25 +21,36 @@ See the companion [Setup Kubernetes](https://github.com/GoogleCloudPlatform/kube
Note: This redis-master is *not* highly available. Making it highly available would be a very interesting, but intricate exersize - redis doesn't actually support multi-master deployments at the time of this writing, so high availability would be a somewhat tricky thing implement, and might involve periodic serialization to disk, and so on.
Use (or just create) the file `examples/guestbook/redis-master.json` which describes a single pod running a redis key-value server in a container:
Use (or just create) the file `examples/guestbook/redis-master-controller.json` which describes a single pod running a redis key-value server in a container:
Note that, although the redis server runs just with a single replica, we use replication controller to enforce that exactly one pod keeps running (e.g. in a event of node going down, the replication controller will ensure that the redis master gets restarted on a healthy node).
```js
{
"id": "redis-master",
"kind": "Pod",
"apiVersion": "v1beta1",
"id": "redis-master-controller",
"kind": "ReplicationController",
"apiVersion": "v1beta1",
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "redis-master",
"containers": [{
"name": "master",
"image": "dockerfile/redis",
"cpu": 100,
"ports": [{
"containerPort": 6379, # containerPort: Where traffic to redis ultimately is routed to.
}]
}]
"replicas": 1,
"replicaSelector": {"name": "redis-master"},
"podTemplate": {
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "redis-master",
"containers": [{
"name": "redis-master",
"image": "dockerfile/redis",
"cpu": 100,
"ports": [{
"containerPort": 6379, # containerPort: Where traffic to redis ultimately is routed to.
}]
}]
}
},
"labels": {
"name": "redis-master",
"app": "redis"
}
}
},
"labels": {
@ -51,31 +62,34 @@ Use (or just create) the file `examples/guestbook/redis-master.json` which descr
Now, create the redis pod in your Kubernetes cluster by running:
```shell
kubectl create -f examples/guestbook/redis-master.json
$ kubectl create -f examples/guestbook/redis-master-controller.json
$ cluster/kubectl.sh get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
redis-master-controller redis-master dockerfile/redis name=redis-master 1
```
Once that's up you can list the pods in the cluster, to verify that the master is running:
```shell
kubectl get pods
$ kubectl get pods
```
You'll see all kubernetes components, most importantly the redis master pod. It will also display the machine that the pod is running on once it gets placed (may take up to thirty seconds):
```shell
NAME IMAGE(S) HOST LABELS STATUS
redis-master dockerfile/redis kubernetes-minion-2.c.myproject.internal/130.211.156.189 name=redis-master Running
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS
redis-master-controller-gb50a 10.244.3.7 redis-master dockerfile/redis kubernetes-minion-7agi.c.hazel-mote-834.internal/104.154.54.203 app=redis,name=redis-master Running
```
If you ssh to that machine, you can run `docker ps` to see the actual pod:
```shell
me@workstation$ gcloud compute ssh --zone us-central1-b kubernetes-minion-2
me@workstation$ gcloud compute ssh kubernetes-minion-7agi
me@kubernetes-minion-2:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e3eed3e5e6d1 dockerfile/redis:latest "redis-server /etc/re 2 minutes ago Up 2 minutes k8s_master.9c0a9146_redis-master.etcd_6296f4bd-70fa-11e4-8469-0800279696e1_45331ebc
me@kubernetes-minion-7agi:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ffef9649265 dockerfile/redis:latest "redis-server /etc/r About a minute ago Up About a minute k8s_redis-master.767aef46_redis-master-controller-gb50a.default.api_4530d7b3-ae5d-11e4-bf77-42010af0d719_579ee964
```
(Note that initial `docker pull` may take a few minutes, depending on network conditions. You can monitor the status of this by running `journalctl -f -u docker` to check when the image is being downloaded. Of course, you can also run `journalctl -f -u kubelet` to see what state the kubelet is in as well during this time.
@ -113,14 +127,11 @@ to create the service by running:
$ kubectl create -f examples/guestbook/redis-master-service.json
redis-master
$ cluster/kubectl.sh get services
NAME LABELS SELECTOR IP PORT
kubernetes <none> component=apiserver,provider=kubernetes 10.0.29.11 443
kubernetes-ro <none> component=apiserver,provider=kubernetes 10.0.141.25 80
redis-master name=redis-master name=redis-master 10.0.16.143 6379
$ kubectl get services
NAME LABELS SELECTOR IP PORT
redis-master name=redis-master name=redis-master 10.0.246.242 6379
```
This will cause all pods to see the redis master apparently running on <ip>:6379. The traffic flow from slaves to masters can be described in two steps, like so.
- A *redis slave* will connect to "port" on the *redis master service*
@ -140,26 +151,28 @@ Use the file `examples/guestbook/redis-slave-controller.json`, which looks like
"apiVersion": "v1beta1",
"desiredState": {
"replicas": 2,
"replicaSelector": {"name": "redisslave"},
"replicaSelector": {"name": "redis-slave"},
"podTemplate": {
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "redis-slave-controller",
"id": "redis-slave",
"containers": [{
"name": "slave",
"name": "redis-slave",
"image": "brendanburns/redis-slave",
"cpu": 200,
"ports": [{"containerPort": 6379, "hostPort": 6380}]
"ports": [{"containerPort": 6379}]
}]
}
},
"labels": {
"name": "redisslave",
"uses": "redis-master"
}
}},
"labels": {"name": "redisslave"}
},
"labels": {
"name": "redis-slave",
"uses": "redis-master",
"app": "redis"
}
}
},
"labels": {"name": "redis-slave"}
}
```
@ -169,9 +182,10 @@ to create the replication controller by running:
$ kubectl create -f examples/guestbook/redis-slave-controller.json
redis-slave-controller
# kubectl.sh get replicationcontrollers
NAME IMAGE(S) SELECTOR REPLICAS
redis-slave-controller brendanburns/redis-slave name=redisslave 2
$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
redis-master-controller redis-master dockerfile/redis name=redis-master 1
redis-slave-controller redis-slave brendanburns/redis-slave name=redis-slave 2
```
The redis slave configures itself by looking for the Kubernetes service environment variables in the container environment. In particular, the redis slave is started with the following command:
@ -186,10 +200,10 @@ Once that's up you can list the pods in the cluster, to verify that the master a
```shell
$ kubectl get pods
NAME IMAGE(S) HOST LABELS STATUS
redis-master dockerfile/redis kubernetes-minion-2.c.myproject.internal/130.211.156.189 name=redis-master Running
ee68394b-7fca-11e4-a220-42010af0a5f1 brendanburns/redis-slave kubernetes-minion-3.c.myproject.internal/130.211.179.212 name=redisslave,uses=redis-master Running
ee694768-7fca-11e4-a220-42010af0a5f1 brendanburns/redis-slave kubernetes-minion-4.c.myproject.internal/130.211.168.210 name=redisslave,uses=redis-master Running
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS
redis-master-controller-gb50a 10.244.3.7 redis-master dockerfile/redis kubernetes-minion-7agi.c.hazel-mote-834.internal/104.154.54.203 app=redis,name=redis-master Running
redis-slave-controller-182tv 10.244.3.6 redis-slave brendanburns/redis-slave kubernetes-minion-7agi.c.hazel-mote-834.internal/104.154.54.203 app=redis,name=redis-slave,uses=redis-master Running
redis-slave-controller-zwk1b 10.244.2.8 redis-slave brendanburns/redis-slave kubernetes-minion-3vxa.c.hazel-mote-834.internal/104.154.54.6 app=redis,name=redis-slave,uses=redis-master Running
```
You will see a single redis master pod and two redis slave pods.
@ -208,29 +222,26 @@ The service specification for the slaves is in `examples/guestbook/redis-slave-s
"port": 6379,
"containerPort": 6379,
"labels": {
"name": "redisslave"
"name": "redis-slave"
},
"selector": {
"name": "redisslave"
"name": "redis-slave"
}
}
```
This time the selector for the service is `name=redisslave`, because that identifies the pods running redis slaves. It may also be helpful to set labels on your service itself as we've done here to make it easy to locate them with the `cluster/kubectl.sh get services -l "label=value"` command.
This time the selector for the service is `name=redis-slave`, because that identifies the pods running redis slaves. It may also be helpful to set labels on your service itself as we've done here to make it easy to locate them with the `cluster/kubectl.sh get services -l "label=value"` command.
Now that you have created the service specification, create it in your cluster by running:
```shell
$ cluster/kubectl.sh create -f examples/guestbook/redis-slave-service.json
$ kubectl create -f examples/guestbook/redis-slave-service.json
redisslave
$ cluster/kubectl.sh get services
NAME LABELS SELECTOR IP PORT
kubernetes <none> component=apiserver,provider=kubernetes 10.0.29.11 443
kubernetes-ro <none> component=apiserver,provider=kubernetes 10.0.141.25 80
redis-master name=redis-master name=redis-master 10.0.16.143 6379
redisslave name=redisslave name=redisslave 10.0.217.148 6379
$ kubectl get services
NAME LABELS SELECTOR IP PORT
redis-master name=redis-master name=redis-master 10.0.246.242 6379
redisslave name=redis-slave name=redis-slave 10.0.72.62 6379
```
### Step Five: Create the frontend pod
@ -253,19 +264,20 @@ The pod is described in the file `examples/guestbook/frontend-controller.json`:
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "frontend-controller",
"id": "frontend",
"containers": [{
"name": "php-redis",
"image": "kubernetes/example-guestbook-php-redis",
"cpu": 100,
"memory": 50000000,
"ports": [{"containerPort": 80, "hostPort": 8000}]
"ports": [{"name": "http-server", "containerPort": 80}]
}]
}
},
"labels": {
"name": "frontend",
"uses": "redisslave,redis-master"
"uses": "redis-slave,redis-master",
"app": "frontend"
}
}},
"labels": {"name": "frontend"}
@ -275,26 +287,27 @@ The pod is described in the file `examples/guestbook/frontend-controller.json`:
Using this file, you can turn up your frontend with:
```shell
$ cluster/kubectl.sh create -f examples/guestbook/frontend-controller.json
$ kubectl create -f examples/guestbook/frontend-controller.json
frontend-controller
$ cluster/kubectl.sh get replicationcontrollers
NAME IMAGE(S) SELECTOR REPLICAS
redis-slave-controller brendanburns/redis-slave name=redisslave 2
frontend-controller kubernetes/example-guestbook-php-redis name=frontend 3
$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
frontend-controller php-redis kubernetes/example-guestbook-php-redis name=frontend 3
redis-master-controller redis-master dockerfile/redis name=redis-master 1
redis-slave-controller redis-slave brendanburns/redis-slave name=redis-slave 2
```
Once that's up (it may take ten to thirty seconds to create the pods) you can list the pods in the cluster, to verify that the master, slaves and frontends are running:
```shell
$ cluster/kubectl.sh get pods
NAME IMAGE(S) HOST LABELS STATUS
redis-master dockerfile/redis kubernetes-minion-2.c.myproject.internal/130.211.156.189 name=redis-master Running
ee68394b-7fca-11e4-a220-42010af0a5f1 brendanburns/redis-slave kubernetes-minion-3.c.myproject.internal/130.211.179.212 name=redisslave,uses=redis-master Running
ee694768-7fca-11e4-a220-42010af0a5f1 brendanburns/redis-slave kubernetes-minion-4.c.myproject.internal/130.211.168.210 name=redisslave,uses=redis-master Running
9fbad0d6-7fcb-11e4-a220-42010af0a5f1 kubernetes/example-guestbook-php-redis kubernetes-minion-1.c.myproject.internal/130.211.185.78 name=frontend,uses=redisslave,redis-master Running
9fbbf70e-7fcb-11e4-a220-42010af0a5f1 kubernetes/example-guestbook-php-redis kubernetes-minion-2.c.myproject.internal/130.211.156.189 name=frontend,uses=redisslave,redis-master Running
9fbdbeca-7fcb-11e4-a220-42010af0a5f1 kubernetes/example-guestbook-php-redis kubernetes-minion-4.c.myproject.internal/130.211.168.210 name=frontend,uses=redisslave,redis-master Running
$ kubectl get pods
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS
frontend-controller-5m1zc 10.244.1.131 php-redis kubernetes/example-guestbook-php-redis kubernetes-minion-3vxa.c.hazel-mote-834.internal/146.148.71.71 app=frontend,name=frontend,uses=redis-slave,redis-master Running
frontend-controller-ckn42 10.244.2.134 php-redis kubernetes/example-guestbook-php-redis kubernetes-minion-by92.c.hazel-mote-834.internal/104.154.54.6 app=frontend,name=frontend,uses=redis-slave,redis-master Running
frontend-controller-v5drx 10.244.0.128 php-redis kubernetes/example-guestbook-php-redis kubernetes-minion-wilb.c.hazel-mote-834.internal/23.236.61.63 app=frontend,name=frontend,uses=redis-slave,redis-master Running
redis-master-controller-gb50a 10.244.3.7 redis-master dockerfile/redis kubernetes-minion-7agi.c.hazel-mote-834.internal/104.154.54.203 app=redis,name=redis-master Running
redis-slave-controller-182tv 10.244.3.6 redis-slave brendanburns/redis-slave kubernetes-minion-7agi.c.hazel-mote-834.internal/104.154.54.203 app=redis,name=redis-slave,uses=redis-master Running
redis-slave-controller-zwk1b 10.244.2.8 redis-slave brendanburns/redis-slave kubernetes-minion-3vxa.c.hazel-mote-834.internal/104.154.54.6 app=redis,name=redis-slave,uses=redis-master Running
```
You will see a single redis master pod, two redis slaves, and three frontend pods.
@ -341,14 +354,51 @@ if (isset($_GET['cmd']) === true) {
} ?>
```
To play with the service itself, find the name of a frontend,
### Step Six: Create the guestbook service.
Just like the others, you want a service to group your frontend pods.
The service is described in the file `examples/guestbook/frontend-service.json`:
```js
{
"id": "frontend",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 8000,
"containerPort": "http-server",
"selector": {
"name": "frontend"
},
"labels": {
"name": "frontend"
},
"createExternalLoadBalancer": true
}
```
```shell
$ kubectl create -f examples/guestbook/frontend-service.json
frontend
$ kubectl get services
NAME LABELS SELECTOR IP PORT
frontend name=frontend name=frontend 10.0.93.211 8000
redis-master name=redis-master name=redis-master 10.0.246.242 6379
redisslave name=redis-slave name=redis-slave 10.0.72.62 6379
```
### A few Google Container Engine specifics for playing around with the services.
- In GCE, you can grab the external IP of that host from the [Google Cloud Console][cloud-console] or the `gcloud` tool, and visit `http://<host-ip>:8000`.
In GCE, `cluster/kubectl.sh` automatically creates forwarding rule for services with `createExternalLoadBalancer`.
```shell
$ gcloud compute instances list
$ gcloud compute forwarding-rules list
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET
frontend us-central1 130.211.188.51 TCP us-central1/targetPools/frontend
```
You can grab the external IP of the load balancer associated with that rule and visit `http://130.211.188.51:8000`.
In GCE, you also may need to open the firewall for port 8000 using the [console][cloud-console] or the `gcloud` tool. The following command will allow traffic from any source to instances tagged `kubernetes-minion`:
```shell
@ -364,7 +414,7 @@ In other environments, you can get the service IP from looking at the output of
And of course, finally, if you are running Kubernetes locally, you can just visit http://localhost:8000.
### Step Six: Cleanup
### Step Seven: Cleanup
To turn down a Kubernetes cluster, if you ran this from source, you can use

View File

@ -9,19 +9,20 @@
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "frontend-controller",
"id": "frontend",
"containers": [{
"name": "php-redis",
"image": "kubernetes/example-guestbook-php-redis",
"cpu": 100,
"memory": 50000000,
"ports": [{"containerPort": 80, "hostPort": 8000}]
"ports": [{"name": "http-server", "containerPort": 80}]
}]
}
},
"labels": {
"name": "frontend",
"uses": "redisslave,redis-master"
"uses": "redis-slave,redis-master",
"app": "frontend"
}
}},
"labels": {"name": "frontend"}

View File

@ -2,12 +2,13 @@
"id": "frontend",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 80,
"containerPort": 80,
"port": 8000,
"containerPort": "http-server",
"selector": {
"name": "frontend"
},
"labels": {
"name": "frontend"
}
},
"createExternalLoadBalancer": true
}

View File

@ -0,0 +1,31 @@
{
"id": "redis-master-controller",
"kind": "ReplicationController",
"apiVersion": "v1beta1",
"desiredState": {
"replicas": 1,
"replicaSelector": {"name": "redis-master"},
"podTemplate": {
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "redis-master",
"containers": [{
"name": "redis-master",
"image": "dockerfile/redis",
"cpu": 100,
"ports": [{"containerPort": 6379}]
}]
}
},
"labels": {
"name": "redis-master",
"app": "redis"
}
}
},
"labels": {
"name": "redis-master"
}
}

View File

@ -1,24 +0,0 @@
{
"id": "redis-master",
"kind": "Pod",
"apiVersion": "v1beta1",
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "redis-master",
"containers": [{
"name": "master",
"image": "dockerfile/redis",
"cpu": 100,
"ports": [{
"containerPort": 6379,
"hostPort": 6379
}]
}]
}
},
"labels": {
"name": "redis-master"
}
}

View File

@ -4,25 +4,26 @@
"apiVersion": "v1beta1",
"desiredState": {
"replicas": 2,
"replicaSelector": {"name": "redisslave"},
"replicaSelector": {"name": "redis-slave"},
"podTemplate": {
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "redis-slave-controller",
"id": "redis-slave",
"containers": [{
"name": "slave",
"name": "redis-slave",
"image": "brendanburns/redis-slave",
"cpu": 200,
"ports": [{"containerPort": 6379, "hostPort": 6380}]
"ports": [{"containerPort": 6379}]
}]
}
},
"labels": {
"name": "redisslave",
"uses": "redis-master"
"name": "redis-slave",
"uses": "redis-master",
"app": "redis"
}
}
},
"labels": {"name": "redisslave"}
"labels": {"name": "redis-slave"}
}

View File

@ -5,9 +5,9 @@
"port": 6379,
"containerPort": 6379,
"labels": {
"name": "redisslave"
"name": "redis-slave"
},
"selector": {
"name": "redisslave"
"name": "redis-slave"
}
}

View File

@ -8,7 +8,7 @@
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "invalid-pod",
"id": "valid-pod",
"containers": [{
"name": "kubernetes-serve-hostname",
"image": "kubernetes/serve_hostname",
@ -17,4 +17,4 @@
}]
}
},
}
}

View File

@ -132,67 +132,68 @@ for version in "${kube_api_versions[@]}"; do
kube::log::status "Testing kubectl(${version}:pods)"
kubectl get pods "${kube_flags[@]}"
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl create -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
kubectl get pods "${kube_flags[@]}"
kubectl get pod redis-master "${kube_flags[@]}"
[ "$(kubectl get pod redis-master -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "redis-master" ]
output_pod=$(kubectl get pod redis-master -o yaml --output-version=v1beta1 "${kube_flags[@]}")
kubectl delete pod redis-master "${kube_flags[@]}"
kubectl get pod valid-pod "${kube_flags[@]}"
[ "$(kubectl get pod valid-pod -o template --output-version=v1beta1 -t '{{ .id }}' "${kube_flags[@]}")" == "valid-pod" ]
output_pod=$(kubectl get pod valid-pod -o yaml --output-version=v1beta1 "${kube_flags[@]}")
kubectl delete pod valid-pod "${kube_flags[@]}"
before="$(kubectl get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
echo "${output_pod}" | kubectl create -f - "${kube_flags[@]}"
after="$(kubectl get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$((${after} - ${before}))" -eq 1 ]
kubectl get pods -o yaml --output-version=v1beta1 "${kube_flags[@]}" | grep -q "id: redis-master"
kubectl describe pod redis-master "${kube_flags[@]}" | grep -q 'Name:.*redis-master'
kubectl delete -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl delete pods -l name=redis-master "${kube_flags[@]}"
[ ! $(kubectl get pods "${kube_flags[@]}" -lname=redis-master | grep -q 'redis-master') ]
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl get pods "${kube_flags[@]}" -lname=redis-master | grep -q 'redis-master'
kubectl get pods -o yaml --output-version=v1beta1 "${kube_flags[@]}" | grep -q "id: valid-pod"
kubectl describe pod valid-pod "${kube_flags[@]}" | grep -q 'Name:.*valid-pod'
kubectl delete -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
kubectl delete pods -l name=valid-pod "${kube_flags[@]}"
[ ! $(kubectl get pods "${kube_flags[@]}" -lname=valid-pod | grep -q 'valid-pod') ]
kubectl create -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
kubectl get pods "${kube_flags[@]}" -lname=valid-pod | grep -q 'valid-pod'
[ ! $(kubectl delete pods "${kube_flags[@]}" ) ]
kubectl get pods "${kube_flags[@]}" -lname=redis-master | grep -q 'redis-master'
[ ! $(kubectl delete pods --all pods -l name=redis-master "${kube_flags[@]}" ) ] # not --all and label selector together
kubectl get pods "${kube_flags[@]}" -lname=valid-pod | grep -q 'valid-pod'
[ ! $(kubectl delete pods --all pods -l name=valid-pod "${kube_flags[@]}" ) ] # not --all and label selector together
kubectl delete --all pods "${kube_flags[@]}" # --all remove all the pods
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl create -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
kubectl create -f examples/redis/redis-proxy.yaml "${kube_flags[@]}"
kubectl get pods redis-master redis-proxy "${kube_flags[@]}"
kubectl delete pods redis-master redis-proxy # delete multiple pods at once
kubectl get pods valid-pod redis-proxy "${kube_flags[@]}"
kubectl delete pods valid-pod redis-proxy "${kube_flags[@]}" # delete multiple pods at once
howmanypods="$(kubectl get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$howmanypods" -eq 0 ]
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl create -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
kubectl create -f examples/redis/redis-proxy.yaml "${kube_flags[@]}"
kubectl stop pods redis-master redis-proxy # stop multiple pods at once
kubectl stop pods valid-pod redis-proxy "${kube_flags[@]}" # stop multiple pods at once
howmanypods="$(kubectl get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$howmanypods" -eq 0 ]
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl create -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
howmanypods="$(kubectl get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$howmanypods" -eq 1 ]
#testing pods and label command command
kubectl label pods redis-master new-name=new-redis-master "${kube_flags[@]}"
kubectl delete pods -lnew-name=new-redis-master "${kube_flags[@]}"
kubectl label pods valid-pod new-name=new-valid-pod "${kube_flags[@]}"
kubectl delete pods -lnew-name=new-valid-pod "${kube_flags[@]}"
howmanypods="$(kubectl get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$howmanypods" -eq 0 ]
kubectl create -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl create -f examples/limitrange/valid-pod.json "${kube_flags[@]}"
howmanypods="$(kubectl get pods -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$howmanypods" -eq 1 ]
! $(kubectl label pods redis-master name=redis-super-sayan "${kube_flags[@]}" )
kubectl label --overwrite pods redis-master name=redis-super-sayan "${kube_flags[@]}"
kubectl delete pods -lname=redis-super-sayan "${kube_flags[@]}"
howmanypods="$(kubectl get pods -lname=redis-super-sayan -o template -t "{{ len .items }}" "${kube_flags[@]}")"
! $(kubectl label pods valid-pod name=valid-pod-super-sayan "${kube_flags[@]}" )
kubectl label --overwrite pods valid-pod name=valid-pod-super-sayan "${kube_flags[@]}"
kubectl delete pods -lname=valid-pod-super-sayan "${kube_flags[@]}"
howmanypods="$(kubectl get pods -lname=valid-pod-super-sayan -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$howmanypods" -eq 0 ]
# make calls in another namespace
kubectl create --namespace=other -f examples/guestbook/redis-master.json "${kube_flags[@]}"
kubectl get pod --namespace=other redis-master
kubectl delete pod --namespace=other redis-master
kubectl create "${kube_flags[@]}" --namespace=other -f examples/limitrange/valid-pod.json
kubectl get "${kube_flags[@]}" pod --namespace=other valid-pod
kubectl delete "${kube_flags[@]}" pod --namespace=other valid-pod
kube::log::status "Testing kubectl(${version}:services)"
kubectl get services "${kube_flags[@]}"
kubectl create -f examples/guestbook/frontend-service.json "${kube_flags[@]}"
kubectl create -f examples/guestbook/redis-master-service.json "${kube_flags[@]}"
kubectl get services "${kube_flags[@]}"
output_service=$(kubectl get service frontend -o json --output-version=v1beta3 "${kube_flags[@]}")
kubectl delete service frontend "${kube_flags[@]}"
output_service=$(kubectl get service redis-master -o json --output-version=v1beta3 "${kube_flags[@]}")
kubectl delete service redis-master "${kube_flags[@]}"
echo "${output_service}" | kubectl create -f - "${kube_flags[@]}"
kubectl create -f - "${kube_flags[@]}" << __EOF__
{
@ -206,15 +207,15 @@ for version in "${kube_api_versions[@]}"; do
}
}
__EOF__
kubectl update service service-${version}-test --patch="{\"selector\":{\"version\":\"${version}\"},\"apiVersion\":\"${version}\"}"
kubectl get service service-${version}-test -o json | kubectl update -f -
kubectl update service "${kube_flags[@]}" service-${version}-test --patch="{\"selector\":{\"version\":\"${version}\"},\"apiVersion\":\"${version}\"}"
kubectl get service "${kube_flags[@]}" service-${version}-test -o json | kubectl update "${kube_flags[@]}" -f -
kubectl get services "${kube_flags[@]}"
kubectl get services "service-${version}-test" "${kube_flags[@]}"
kubectl delete service frontend "${kube_flags[@]}"
kubectl delete service redis-master "${kube_flags[@]}"
servicesbefore="$(kubectl get services -o template -t "{{ len .items }}" "${kube_flags[@]}")"
kubectl create -f examples/guestbook/frontend-service.json "${kube_flags[@]}"
kubectl create -f examples/guestbook/redis-master-service.json "${kube_flags[@]}"
kubectl create -f examples/guestbook/redis-slave-service.json "${kube_flags[@]}"
kubectl delete services frontend redisslave # delete multiple services at once
kubectl delete services redis-master redisslave "${kube_flags[@]}" # delete multiple services at once
servicesafter="$(kubectl get services -o template -t "{{ len .items }}" "${kube_flags[@]}")"
[ "$((${servicesafter} - ${servicesbefore}))" -eq 0 ]

View File

@ -25,8 +25,8 @@ import (
)
func TestCreateObject(t *testing.T) {
pods, _ := testData()
pods.Items[0].Name = "redis-master"
_, _, rc := testData()
rc.Items[0].Name = "redis-master-controller"
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -34,8 +34,8 @@ func TestCreateObject(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &rc.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
@ -46,17 +46,17 @@ func TestCreateObject(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdCreate(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
if buf.String() != "redis-master\n" {
if buf.String() != "redis-master-controller\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestCreateMultipleObject(t *testing.T) {
pods, svc := testData()
_, svc, rc := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -64,10 +64,10 @@ func TestCreateMultipleObject(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/services" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &svc.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &rc.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
@ -78,19 +78,19 @@ func TestCreateMultipleObject(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdCreate(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
cmd.Run(cmd, []string{})
// Names should come from the REST response, NOT the files
if buf.String() != "foo\nbaz\n" {
if buf.String() != "rc1\nbaz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestCreateDirectory(t *testing.T) {
pods, svc := testData()
pods.Items[0].Name = "redis-master"
_, svc, rc := testData()
rc.Items[0].Name = "name"
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -98,12 +98,10 @@ func TestCreateDirectory(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/services" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &svc.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers" && m == "POST":
return &http.Response{StatusCode: 201, Body: objBody(codec, &svc.Items[0])}, nil
return &http.Response{StatusCode: 201, Body: objBody(codec, &rc.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
@ -117,7 +115,7 @@ func TestCreateDirectory(t *testing.T) {
cmd.Flags().Set("filename", "../../../examples/guestbook")
cmd.Run(cmd, []string{})
if buf.String() != "baz\nbaz\nbaz\nredis-master\nbaz\nbaz\n" {
if buf.String() != "name\nbaz\nname\nbaz\nname\nbaz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}

View File

@ -26,7 +26,7 @@ import (
)
func TestDeleteObject(t *testing.T) {
pods, _ := testData()
_, _, rc := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -34,8 +34,8 @@ func TestDeleteObject(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods/redis-master" && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
@ -46,11 +46,11 @@ func TestDeleteObject(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdDelete(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
if buf.String() != "redis-master\n" {
if buf.String() != "redis-master-controller\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@ -62,7 +62,7 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods/redis-master" && m == "DELETE":
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE":
return &http.Response{StatusCode: 404, Body: stringBody("")}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
@ -74,7 +74,7 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdDelete(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Run(cmd, []string{})
if buf.String() != "" {
@ -83,7 +83,7 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
}
func TestDeleteMultipleObject(t *testing.T) {
pods, svc := testData()
_, svc, rc := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -91,8 +91,8 @@ func TestDeleteMultipleObject(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods/redis-master" && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil
case p == "/namespaces/test/services/frontend" && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
default:
@ -105,17 +105,17 @@ func TestDeleteMultipleObject(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdDelete(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
cmd.Run(cmd, []string{})
if buf.String() != "redis-master\nfrontend\n" {
if buf.String() != "redis-master-controller\nfrontend\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) {
_, svc := testData()
_, svc, _ := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -123,7 +123,7 @@ func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods/redis-master" && m == "DELETE":
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "DELETE":
return &http.Response{StatusCode: 404, Body: stringBody("")}, nil
case p == "/namespaces/test/services/frontend" && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
@ -137,7 +137,7 @@ func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdDelete(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
cmd.Run(cmd, []string{})
@ -147,7 +147,7 @@ func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) {
}
func TestDeleteDirectory(t *testing.T) {
pods, svc := testData()
_, svc, rc := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -155,12 +155,10 @@ func TestDeleteDirectory(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case strings.HasPrefix(p, "/namespaces/test/pods/") && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case strings.HasPrefix(p, "/namespaces/test/services/") && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
case strings.HasPrefix(p, "/namespaces/test/replicationcontrollers/") && m == "DELETE":
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
@ -174,13 +172,13 @@ func TestDeleteDirectory(t *testing.T) {
cmd.Flags().Set("filename", "../../../examples/guestbook")
cmd.Run(cmd, []string{})
if buf.String() != "frontend-controller\nfrontend\nredis-master\nredis-master\nredis-slave-controller\nredisslave\n" {
if buf.String() != "frontend-controller\nfrontend\nredis-master-controller\nredis-master\nredis-slave-controller\nredisslave\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestDeleteMultipleSelector(t *testing.T) {
pods, svc := testData()
pods, svc, _ := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}

View File

@ -34,7 +34,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json"
)
func testData() (*api.PodList, *api.ServiceList) {
func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) {
pods := &api.PodList{
ListMeta: api.ListMeta{
ResourceVersion: "15",
@ -70,7 +70,20 @@ func testData() (*api.PodList, *api.ServiceList) {
},
},
}
return pods, svc
rc := &api.ReplicationControllerList{
ListMeta: api.ListMeta{
ResourceVersion: "17",
},
Items: []api.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "rc1", Namespace: "test", ResourceVersion: "18"},
Spec: api.ReplicationControllerSpec{
Replicas: 1,
},
},
},
}
return pods, svc, rc
}
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
@ -123,7 +136,7 @@ func TestGetSchemaObject(t *testing.T) {
}
func TestGetObjects(t *testing.T) {
pods, _ := testData()
pods, _, _ := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -149,7 +162,7 @@ func TestGetObjects(t *testing.T) {
}
func TestGetListObjects(t *testing.T) {
pods, _ := testData()
pods, _, _ := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -175,7 +188,7 @@ func TestGetListObjects(t *testing.T) {
}
func TestGetMultipleTypeObjects(t *testing.T) {
pods, svc := testData()
pods, svc, _ := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -211,7 +224,7 @@ func TestGetMultipleTypeObjects(t *testing.T) {
}
func TestGetMultipleTypeObjectsAsList(t *testing.T) {
pods, svc := testData()
pods, svc, _ := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -260,7 +273,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
}
func TestGetMultipleTypeObjectsWithSelector(t *testing.T) {
pods, svc := testData()
pods, svc, _ := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}

View File

@ -22,26 +22,11 @@ import (
"strings"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
func rcTestData() *api.ReplicationControllerList {
rc := &api.ReplicationControllerList{
ListMeta: api.ListMeta{
ResourceVersion: "17",
},
Items: []api.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "qux", Namespace: "test", ResourceVersion: "13"},
},
},
}
return rc
}
func TestUpdateObject(t *testing.T) {
pods, _ := testData()
_, _, rc := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -49,10 +34,10 @@ func TestUpdateObject(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods/redis-master" && m == "GET":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/pods/redis-master" && m == "PUT":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "GET":
return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "PUT":
return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
@ -63,17 +48,17 @@ func TestUpdateObject(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdUpdate(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
if buf.String() != "foo\n" {
if buf.String() != "rc1\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestUpdateMultipleObject(t *testing.T) {
pods, svc := testData()
_, svc, rc := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -81,11 +66,10 @@ func TestUpdateMultipleObject(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods/redis-master" && m == "GET":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/pods/redis-master" && m == "PUT":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "GET":
return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil
case p == "/namespaces/test/replicationcontrollers/redis-master-controller" && m == "PUT":
return &http.Response{StatusCode: 200, Body: objBody(codec, &rc.Items[0])}, nil
case p == "/namespaces/test/services/frontend" && m == "GET":
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
case p == "/namespaces/test/services/frontend" && m == "PUT":
@ -100,18 +84,17 @@ func TestUpdateMultipleObject(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := f.NewCmdUpdate(buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
cmd.Run(cmd, []string{})
if buf.String() != "foo\nbaz\n" {
if buf.String() != "rc1\nbaz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestUpdateDirectory(t *testing.T) {
pods, svc := testData()
rc := rcTestData()
_, svc, rc := testData()
f, tf, codec := NewAPIFactory()
tf.Printer = &testPrinter{}
@ -119,8 +102,6 @@ func TestUpdateDirectory(t *testing.T) {
Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case strings.HasPrefix(p, "/namespaces/test/pods/") && (m == "GET" || m == "PUT"):
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
case strings.HasPrefix(p, "/namespaces/test/services/") && (m == "GET" || m == "PUT"):
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
case strings.HasPrefix(p, "/namespaces/test/replicationcontrollers/") && (m == "GET" || m == "PUT"):
@ -139,7 +120,7 @@ func TestUpdateDirectory(t *testing.T) {
cmd.Flags().Set("namespace", "test")
cmd.Run(cmd, []string{})
if buf.String() != "qux\nbaz\nbaz\nfoo\nqux\nbaz\n" {
if buf.String() != "rc1\nbaz\nrc1\nbaz\nrc1\nbaz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}

View File

@ -166,7 +166,7 @@ func (v *testVisitor) Objects() []runtime.Object {
func TestPathBuilder(t *testing.T) {
b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()).
FilenameParam("../../../examples/guestbook/redis-master.json")
FilenameParam("../../../examples/guestbook/redis-master-controller.json")
test := &testVisitor{}
singular := false
@ -177,7 +177,7 @@ func TestPathBuilder(t *testing.T) {
}
info := test.Infos[0]
if info.Name != "redis-master" || info.Namespace != "" || info.Object == nil {
if info.Name != "redis-master-controller" || info.Namespace != "" || info.Object == nil {
t.Errorf("unexpected info: %#v", info)
}
}
@ -215,8 +215,8 @@ func TestNodeBuilder(t *testing.T) {
func TestPathBuilderWithMultiple(t *testing.T) {
b := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()).
FilenameParam("../../../examples/guestbook/redis-master.json").
FilenameParam("../../../examples/guestbook/redis-master.json").
FilenameParam("../../../examples/guestbook/redis-master-controller.json").
FilenameParam("../../../examples/guestbook/redis-master-controller.json").
NamespaceParam("test").DefaultNamespace()
test := &testVisitor{}
@ -228,7 +228,7 @@ func TestPathBuilderWithMultiple(t *testing.T) {
}
info := test.Infos[1]
if info.Name != "redis-master" || info.Namespace != "test" || info.Object == nil {
if info.Name != "redis-master-controller" || info.Namespace != "test" || info.Object == nil {
t.Errorf("unexpected info: %#v", info)
}
}
@ -248,7 +248,7 @@ func TestDirectoryBuilder(t *testing.T) {
found := false
for _, info := range test.Infos {
if info.Name == "redis-master" && info.Namespace == "test" && info.Object != nil {
if info.Name == "redis-master-controller" && info.Namespace == "test" && info.Object != nil {
found = true
}
}
@ -474,7 +474,7 @@ func TestMultipleObject(t *testing.T) {
func TestSingularObject(t *testing.T) {
obj, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()).
NamespaceParam("test").DefaultNamespace().
FilenameParam("../../../examples/guestbook/redis-master.json").
FilenameParam("../../../examples/guestbook/redis-master-controller.json").
Flatten().
Do().Object()
@ -482,12 +482,12 @@ func TestSingularObject(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
pod, ok := obj.(*api.Pod)
rc, ok := obj.(*api.ReplicationController)
if !ok {
t.Fatalf("unexpected object: %#v", obj)
}
if pod.Name != "redis-master" || pod.Namespace != "test" {
t.Errorf("unexpected pod: %#v", pod)
if rc.Name != "redis-master-controller" || rc.Namespace != "test" {
t.Errorf("unexpected controller: %#v", rc)
}
}
@ -550,16 +550,16 @@ func TestListObjectWithDifferentVersions(t *testing.T) {
}
func TestWatch(t *testing.T) {
pods, _ := testData()
_, svc := testData()
w, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClientWith(t, map[string]string{
"/watch/namespaces/test/pods/redis-master?resourceVersion=10": watchBody(watch.Event{
"/watch/namespaces/test/services/redis-master?resourceVersion=12": watchBody(watch.Event{
Type: watch.Added,
Object: &pods.Items[0],
Object: &svc.Items[0],
}),
})).
NamespaceParam("test").DefaultNamespace().
FilenameParam("../../../examples/guestbook/redis-master.json").Flatten().
Do().Watch("10")
FilenameParam("../../../examples/guestbook/redis-master-service.json").Flatten().
Do().Watch("12")
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -572,12 +572,12 @@ func TestWatch(t *testing.T) {
if obj.Type != watch.Added {
t.Fatalf("unexpected watch event", obj)
}
pod, ok := obj.Object.(*api.Pod)
service, ok := obj.Object.(*api.Service)
if !ok {
t.Fatalf("unexpected object: %#v", obj)
}
if pod.Name != "foo" || pod.ResourceVersion != "10" {
t.Errorf("unexpected pod: %#v", pod)
if service.Name != "baz" || service.ResourceVersion != "12" {
t.Errorf("unexpected service: %#v", service)
}
}
}
@ -585,8 +585,8 @@ func TestWatch(t *testing.T) {
func TestWatchMultipleError(t *testing.T) {
_, err := NewBuilder(latest.RESTMapper, api.Scheme, fakeClient()).
NamespaceParam("test").DefaultNamespace().
FilenameParam("../../../examples/guestbook/redis-master.json").Flatten().
FilenameParam("../../../examples/guestbook/redis-master.json").Flatten().
FilenameParam("../../../examples/guestbook/redis-master-controller.json").Flatten().
FilenameParam("../../../examples/guestbook/redis-master-controller.json").Flatten().
Do().Watch("")
if err == nil {