mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
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:
commit
f2698e5905
@ -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{},
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"}
|
||||
|
@ -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
|
||||
}
|
||||
|
31
examples/guestbook/redis-master-controller.json
Normal file
31
examples/guestbook/redis-master-controller.json
Normal 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"
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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"}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@
|
||||
"port": 6379,
|
||||
"containerPort": 6379,
|
||||
"labels": {
|
||||
"name": "redisslave"
|
||||
"name": "redis-slave"
|
||||
},
|
||||
"selector": {
|
||||
"name": "redisslave"
|
||||
"name": "redis-slave"
|
||||
}
|
||||
}
|
||||
|
@ -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 @@
|
||||
}]
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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 ]
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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{}
|
||||
|
@ -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{}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user