kubeclient-rollback-dev 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rubocop.yml +16 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +428 -0
  8. data/Rakefile +12 -0
  9. data/kubeclient.gemspec +29 -0
  10. data/lib/kubeclient/common.rb +512 -0
  11. data/lib/kubeclient/config.rb +126 -0
  12. data/lib/kubeclient/entity_list.rb +16 -0
  13. data/lib/kubeclient/kube_exception.rb +14 -0
  14. data/lib/kubeclient/missing_kind_compatibility.rb +68 -0
  15. data/lib/kubeclient/version.rb +4 -0
  16. data/lib/kubeclient/watch_notice.rb +7 -0
  17. data/lib/kubeclient/watch_stream.rb +80 -0
  18. data/lib/kubeclient.rb +32 -0
  19. data/test/cassettes/kubernetes_guestbook.yml +879 -0
  20. data/test/config/allinone.kubeconfig +20 -0
  21. data/test/config/external-ca.pem +18 -0
  22. data/test/config/external-cert.pem +19 -0
  23. data/test/config/external-key.rsa +27 -0
  24. data/test/config/external.kubeconfig +20 -0
  25. data/test/config/nouser.kubeconfig +16 -0
  26. data/test/config/userauth.kubeconfig +28 -0
  27. data/test/json/bindings_list.json +10 -0
  28. data/test/json/component_status.json +17 -0
  29. data/test/json/component_status_list.json +52 -0
  30. data/test/json/config_map_list.json +9 -0
  31. data/test/json/core_api_resource_list.json +181 -0
  32. data/test/json/core_api_resource_list_without_kind.json +129 -0
  33. data/test/json/core_oapi_resource_list_without_kind.json +197 -0
  34. data/test/json/created_endpoint.json +28 -0
  35. data/test/json/created_namespace.json +20 -0
  36. data/test/json/created_secret.json +16 -0
  37. data/test/json/created_service.json +31 -0
  38. data/test/json/empty_pod_list.json +9 -0
  39. data/test/json/endpoint_list.json +48 -0
  40. data/test/json/entity_list.json +56 -0
  41. data/test/json/event_list.json +35 -0
  42. data/test/json/limit_range.json +23 -0
  43. data/test/json/limit_range_list.json +31 -0
  44. data/test/json/namespace.json +13 -0
  45. data/test/json/namespace_exception.json +8 -0
  46. data/test/json/namespace_list.json +32 -0
  47. data/test/json/node.json +29 -0
  48. data/test/json/node_list.json +37 -0
  49. data/test/json/persistent_volume.json +37 -0
  50. data/test/json/persistent_volume_claim.json +32 -0
  51. data/test/json/persistent_volume_claim_list.json +40 -0
  52. data/test/json/persistent_volume_claims_nil_items.json +8 -0
  53. data/test/json/persistent_volume_list.json +45 -0
  54. data/test/json/pod.json +92 -0
  55. data/test/json/pod_list.json +79 -0
  56. data/test/json/pod_template_list.json +9 -0
  57. data/test/json/processed_template.json +27 -0
  58. data/test/json/replication_controller.json +57 -0
  59. data/test/json/replication_controller_list.json +66 -0
  60. data/test/json/resource_quota.json +46 -0
  61. data/test/json/resource_quota_list.json +54 -0
  62. data/test/json/secret_list.json +44 -0
  63. data/test/json/service.json +33 -0
  64. data/test/json/service_account.json +25 -0
  65. data/test/json/service_account_list.json +82 -0
  66. data/test/json/service_illegal_json_404.json +1 -0
  67. data/test/json/service_list.json +97 -0
  68. data/test/json/service_patch.json +25 -0
  69. data/test/json/service_update.json +22 -0
  70. data/test/json/versions_list.json +6 -0
  71. data/test/json/watch_stream.json +3 -0
  72. data/test/test_common.rb +32 -0
  73. data/test/test_component_status.rb +30 -0
  74. data/test/test_config.rb +72 -0
  75. data/test/test_endpoint.rb +35 -0
  76. data/test/test_guestbook_go.rb +238 -0
  77. data/test/test_helper.rb +10 -0
  78. data/test/test_kubeclient.rb +611 -0
  79. data/test/test_limit_range.rb +27 -0
  80. data/test/test_missing_methods.rb +42 -0
  81. data/test/test_namespace.rb +61 -0
  82. data/test/test_node.rb +33 -0
  83. data/test/test_persistent_volume.rb +30 -0
  84. data/test/test_persistent_volume_claim.rb +30 -0
  85. data/test/test_pod.rb +29 -0
  86. data/test/test_pod_log.rb +50 -0
  87. data/test/test_process_template.rb +44 -0
  88. data/test/test_replication_controller.rb +27 -0
  89. data/test/test_resource_list_without_kind.rb +78 -0
  90. data/test/test_resource_quota.rb +25 -0
  91. data/test/test_secret.rb +70 -0
  92. data/test/test_service.rb +293 -0
  93. data/test/test_service_account.rb +28 -0
  94. data/test/test_watch.rb +119 -0
  95. data/test/txt/pod_log.txt +6 -0
  96. data/test/valid_token_file +1 -0
  97. metadata +343 -0
@@ -0,0 +1,82 @@
1
+ {
2
+ "kind": "List",
3
+ "apiVersion": "v1",
4
+ "metadata": {},
5
+ "items": [
6
+ {
7
+ "kind": "ServiceAccount",
8
+ "apiVersion": "v1",
9
+ "metadata": {
10
+ "name": "builder",
11
+ "namespace": "default",
12
+ "selfLink": "/api/v1/namespaces/default/serviceaccounts/builder",
13
+ "uid": "d40655f6-6bf0-11e5-843a-525400f8b93e",
14
+ "resourceVersion": "133",
15
+ "creationTimestamp": "2015-10-06T06:09:39Z"
16
+ },
17
+ "secrets": [
18
+ {
19
+ "name": "builder-token-5v6z2"
20
+ },
21
+ {
22
+ "name": "builder-dockercfg-qe2re"
23
+ }
24
+ ],
25
+ "imagePullSecrets": [
26
+ {
27
+ "name": "builder-dockercfg-qe2re"
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ "kind": "ServiceAccount",
33
+ "apiVersion": "v1",
34
+ "metadata": {
35
+ "name": "default",
36
+ "namespace": "default",
37
+ "selfLink": "/api/v1/namespaces/default/serviceaccounts/default",
38
+ "uid": "d3d773f4-6bf0-11e5-843a-525400f8b93e",
39
+ "resourceVersion": "94",
40
+ "creationTimestamp": "2015-10-06T06:09:39Z"
41
+ },
42
+ "secrets": [
43
+ {
44
+ "name": "default-token-6s23q"
45
+ },
46
+ {
47
+ "name": "default-dockercfg-62tf3"
48
+ }
49
+ ],
50
+ "imagePullSecrets": [
51
+ {
52
+ "name": "default-dockercfg-62tf3"
53
+ }
54
+ ]
55
+ },
56
+ {
57
+ "kind": "ServiceAccount",
58
+ "apiVersion": "v1",
59
+ "metadata": {
60
+ "name": "deployer",
61
+ "namespace": "default",
62
+ "selfLink": "/api/v1/namespaces/default/serviceaccounts/deployer",
63
+ "uid": "d41d385e-6bf0-11e5-843a-525400f8b93e",
64
+ "resourceVersion": "137",
65
+ "creationTimestamp": "2015-10-06T06:09:39Z"
66
+ },
67
+ "secrets": [
68
+ {
69
+ "name": "deployer-token-h3i57"
70
+ },
71
+ {
72
+ "name": "deployer-dockercfg-qgjjj"
73
+ }
74
+ ],
75
+ "imagePullSecrets": [
76
+ {
77
+ "name": "deployer-dockercfg-qgjjj"
78
+ }
79
+ ]
80
+ }
81
+ ]
82
+ }
@@ -0,0 +1 @@
1
+ 404: Page Not Found
@@ -0,0 +1,97 @@
1
+ {
2
+ "kind": "ServiceList",
3
+ "apiVersion": "v1",
4
+ "metadata": {
5
+ "selfLink": "/api/v1/services",
6
+ "resourceVersion": "36727"
7
+ },
8
+ "items": [
9
+ {
10
+ "metadata": {
11
+ "name": "kubernetes",
12
+ "namespace": "default",
13
+ "selfLink": "/api/v1/namespaces/default/services/kubernetes",
14
+ "uid": "b6606490-db86-11e4-b293-f8b156af4ae1",
15
+ "resourceVersion": "6",
16
+ "creationTimestamp": "2015-04-05T11:27:15Z",
17
+ "labels": {
18
+ "component": "apiserver",
19
+ "provider": "kubernetes"
20
+ }
21
+ },
22
+ "spec": {
23
+ "ports": [
24
+ {
25
+ "name": "",
26
+ "protocol": "TCP",
27
+ "port": 443,
28
+ "targetPort": 443
29
+ }
30
+ ],
31
+ "selector": null,
32
+ "clusterIP": "10.0.0.2",
33
+ "sessionAffinity": "None"
34
+ },
35
+ "status": {}
36
+ },
37
+ {
38
+ "metadata": {
39
+ "name": "kubernetes-ro",
40
+ "namespace": "default",
41
+ "selfLink": "/api/v1/namespaces/default/services/kubernetes-ro",
42
+ "uid": "b6606694-db86-11e4-b293-f8b156af4ae1",
43
+ "resourceVersion": "5",
44
+ "creationTimestamp": "2015-04-05T11:27:15Z",
45
+ "labels": {
46
+ "component": "apiserver",
47
+ "provider": "kubernetes"
48
+ }
49
+ },
50
+ "spec": {
51
+ "ports": [
52
+ {
53
+ "name": "",
54
+ "protocol": "TCP",
55
+ "port": 80,
56
+ "targetPort": 80
57
+ }
58
+ ],
59
+ "selector": null,
60
+ "clusterIP": "10.0.0.1",
61
+ "sessionAffinity": "None"
62
+ },
63
+ "status": {}
64
+ },
65
+ {
66
+ "metadata": {
67
+ "name": "redis-slave",
68
+ "namespace": "development",
69
+ "selfLink": "/api/v1/namespaces/development/services/redis-slave",
70
+ "uid": "bdb80a8f-db93-11e4-b293-f8b156af4ae1",
71
+ "resourceVersion": "2815",
72
+ "creationTimestamp": "2015-04-05T13:00:31Z",
73
+ "labels": {
74
+ "name": "redis",
75
+ "role": "slave"
76
+ }
77
+ },
78
+ "spec": {
79
+ "ports": [
80
+ {
81
+ "name": "",
82
+ "protocol": "TCP",
83
+ "port": 6379,
84
+ "targetPort": "redis-server"
85
+ }
86
+ ],
87
+ "selector": {
88
+ "name": "redis",
89
+ "role": "slave"
90
+ },
91
+ "clusterIP": "10.0.0.140",
92
+ "sessionAffinity": "None"
93
+ },
94
+ "status": {}
95
+ }
96
+ ]
97
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "status" : {},
3
+ "kind" : "Service",
4
+ "apiVersion" : "v1",
5
+ "spec" : {
6
+ "ports" : [
7
+ {
8
+ "targetPort" : 80,
9
+ "nodePort" : 0,
10
+ "port" : 80,
11
+ "protocol" : "TCP"
12
+ }
13
+ ],
14
+ "clusterIP" : "1.2.3.4"
15
+ },
16
+ "metadata" : {
17
+ "name" : "my_service",
18
+ "creationTimestamp" : null,
19
+ "namespace" : "development",
20
+ "resourceVersion" : "2",
21
+ "annotations" : {
22
+ "key" : "value"
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "status" : {},
3
+ "kind" : "Service",
4
+ "apiVersion" : "v1",
5
+ "spec" : {
6
+ "ports" : [
7
+ {
8
+ "targetPort" : 80,
9
+ "nodePort" : 0,
10
+ "port" : 80,
11
+ "protocol" : "TCP"
12
+ }
13
+ ],
14
+ "clusterIP" : "1.2.3.4"
15
+ },
16
+ "metadata" : {
17
+ "name" : "my_service",
18
+ "creationTimestamp" : null,
19
+ "namespace" : "default",
20
+ "resourceVersion" : "2"
21
+ }
22
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "versions": [
3
+ "v1beta3",
4
+ "v1"
5
+ ]
6
+ }
@@ -0,0 +1,3 @@
1
+ {"type":"ADDED","object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"php","namespace":"default","selfLink":"/api/v1/pods/php","uid":"e75f2c07-b047-11e4-89e4-525400c903c1","resourceVersion":"1389","creationTimestamp":"2015-02-09T05:39:19-05:00","labels":{"name":"foo"}},"spec":{"volumes":null,"containers":[{"name":"nginx","image":"dockerfile/nginx","ports":[{"hostPort":9090,"containerPort":80,"protocol":"TCP"}],"resources":{},"livenessProbe":{"httpGet":{"path":"/index.html","port":"9090"},"initialDelaySeconds":30},"terminationMessagePath":"/dev/termination-log","imagePullPolicy":"IfNotPresent","securityContext":{"capabilities":{}}}],"restartPolicy":{"always":{}},"dnsPolicy":"ClusterFirst"},"status":{"phase":"Pending"}}}
2
+ {"type":"MODIFIED","object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"php","namespace":"default","selfLink":"/api/v1/pods/php","uid":"e75f2c07-b047-11e4-89e4-525400c903c1","resourceVersion":"1390","creationTimestamp":"2015-02-09T05:39:19-05:00","labels":{"name":"foo"}},"spec":{"volumes":null,"containers":[{"name":"nginx","image":"dockerfile/nginx","ports":[{"hostPort":9090,"containerPort":80,"protocol":"TCP"}],"resources":{},"livenessProbe":{"httpGet":{"path":"/index.html","port":"9090"},"initialDelaySeconds":30},"terminationMessagePath":"/dev/termination-log","imagePullPolicy":"IfNotPresent","securityContext":{"capabilities":{}}}],"restartPolicy":{"always":{}},"dnsPolicy":"ClusterFirst"},"status":{"phase":"Pending","host":"127.0.0.1"}}}
3
+ {"type":"DELETED","object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"php","namespace":"default","selfLink":"/api/v1/pods/php","uid":"e75f2c07-b047-11e4-89e4-525400c903c1","resourceVersion":"1398","creationTimestamp":"2015-02-09T05:39:19-05:00","labels":{"name":"foo"}},"spec":{"volumes":null,"containers":[{"name":"nginx","image":"dockerfile/nginx","ports":[{"hostPort":9090,"containerPort":80,"protocol":"TCP"}],"resources":{},"livenessProbe":{"httpGet":{"path":"/index.html","port":"9090"},"initialDelaySeconds":30},"terminationMessagePath":"/dev/termination-log","imagePullPolicy":"IfNotPresent","securityContext":{"capabilities":{}}}],"restartPolicy":{"always":{}},"dnsPolicy":"ClusterFirst"},"status":{"phase":"Pending","host":"127.0.0.1"}}}
@@ -0,0 +1,32 @@
1
+ require 'test_helper'
2
+
3
+ # Unit tests for the common module
4
+ class CommonTest < MiniTest::Test
5
+ def test_underscore_entity
6
+ %w(
7
+ Pod pod
8
+ Service service
9
+ ReplicationController replication_controller
10
+ Node node
11
+ Event event
12
+ Endpoint endpoint
13
+ Namespace namespace
14
+ Secret secret
15
+ ResourceQuota resource_quota
16
+ LimitRange limit_range
17
+ PersistentVolume persistent_volume
18
+ PersistentVolumeClaim persistent_volume_claim
19
+ ComponentStatus component_status
20
+ ServiceAccount service_account
21
+ Project project
22
+ Route route
23
+ ClusterRoleBinding cluster_role_binding
24
+ Build build
25
+ BuildConfig build_config
26
+ Image image
27
+ ImageStream image_stream
28
+ ).each_slice(2) do |singular, plural|
29
+ assert_equal(Kubeclient::ClientMixin.underscore_entity(singular), plural)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ # ComponentStatus tests
4
+ class TestComponentStatus < MiniTest::Test
5
+ def test_get_from_json_v3
6
+ stub_request(:get, %r{/componentstatuses})
7
+ .to_return(body: open_test_file('component_status.json'), status: 200)
8
+ stub_request(:get, %r{/api/v1$})
9
+ .to_return(body: open_test_file('core_api_resource_list.json'), status: 200)
10
+
11
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
12
+ component_status = client.get_component_status 'etcd-0', 'default'
13
+
14
+ assert_instance_of(Kubeclient::ComponentStatus, component_status)
15
+ assert_equal('etcd-0', component_status.metadata.name)
16
+ assert_equal('Healthy', component_status.conditions[0].type)
17
+ assert_equal('True', component_status.conditions[0].status)
18
+
19
+ assert_requested(
20
+ :get,
21
+ 'http://localhost:8080/api/v1',
22
+ times: 1
23
+ )
24
+ assert_requested(
25
+ :get,
26
+ 'http://localhost:8080/api/v1/namespaces/default/componentstatuses/etcd-0',
27
+ times: 1
28
+ )
29
+ end
30
+ end
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ def test_config_file(name)
4
+ File.new(File.join(File.dirname(__FILE__), 'config', name))
5
+ end
6
+
7
+ # Testing Kubernetes client configuration
8
+ class KubeClientConfigTest < MiniTest::Test
9
+ def test_allinone
10
+ config = Kubeclient::Config.read(test_config_file('allinone.kubeconfig'))
11
+ assert_equal(['default/localhost:8443/system:admin'], config.contexts)
12
+ check_context(config.context, ssl: true)
13
+ end
14
+
15
+ def test_external
16
+ config = Kubeclient::Config.read(test_config_file('external.kubeconfig'))
17
+ assert_equal(['default/localhost:8443/system:admin'], config.contexts)
18
+ check_context(config.context, ssl: true)
19
+ end
20
+
21
+ def test_nouser
22
+ config = Kubeclient::Config.read(test_config_file('nouser.kubeconfig'))
23
+ assert_equal(['default/localhost:8443/nouser'], config.contexts)
24
+ check_context(config.context, ssl: false)
25
+ end
26
+
27
+ def test_user_token
28
+ config = Kubeclient::Config.read(test_config_file('userauth.kubeconfig'))
29
+ assert_equal(['localhost/system:admin:token', 'localhost/system:admin:userpass'],
30
+ config.contexts)
31
+ context = config.context('localhost/system:admin:token')
32
+ check_context(context, ssl: false)
33
+ assert_equal('0123456789ABCDEF0123456789ABCDEF', context.auth_options[:bearer_token])
34
+ end
35
+
36
+ def test_user_password
37
+ config = Kubeclient::Config.read(test_config_file('userauth.kubeconfig'))
38
+ assert_equal(['localhost/system:admin:token', 'localhost/system:admin:userpass'],
39
+ config.contexts)
40
+ context = config.context('localhost/system:admin:userpass')
41
+ check_context(context, ssl: false)
42
+ assert_equal('admin', context.auth_options[:username])
43
+ assert_equal('pAssw0rd123', context.auth_options[:password])
44
+ end
45
+
46
+ private
47
+
48
+ def check_context(context, ssl: true)
49
+ assert_equal('https://localhost:8443', context.api_endpoint)
50
+ assert_equal('v1', context.api_version)
51
+ if ssl
52
+ assert_equal(OpenSSL::SSL::VERIFY_PEER, context.ssl_options[:verify_ssl])
53
+ assert_kind_of(OpenSSL::X509::Store, context.ssl_options[:cert_store])
54
+ assert_kind_of(OpenSSL::X509::Certificate, context.ssl_options[:client_cert])
55
+ assert_kind_of(OpenSSL::PKey::RSA, context.ssl_options[:client_key])
56
+ # When certificates expire the quickest way to recreate them is using
57
+ # an OpenShift tool (100% compatible with kubernetes):
58
+ #
59
+ # $ oc adm ca create-master-certs --hostnames=localhost
60
+ #
61
+ # At the time of this writing the files to be updated are:
62
+ #
63
+ # test/config/allinone.kubeconfig
64
+ # test/config/external-ca.pem
65
+ # test/config/external-cert.pem
66
+ # test/config/external-key.rsa
67
+ assert(context.ssl_options[:cert_store].verify(context.ssl_options[:client_cert]))
68
+ else
69
+ assert_equal(OpenSSL::SSL::VERIFY_NONE, context.ssl_options[:verify_ssl])
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ # Endpoint entity tests
4
+ class TestEndpoint < MiniTest::Test
5
+ def test_create_endpoint
6
+ stub_request(:get, %r{/api/v1$})
7
+ .to_return(
8
+ body: open_test_file('core_api_resource_list.json'),
9
+ status: 200
10
+ )
11
+
12
+ client = Kubeclient::Client.new 'http://localhost:8080/api/', 'v1'
13
+ testing_ep = Kubeclient::Resource.new
14
+ testing_ep.metadata = {}
15
+ testing_ep.metadata.name = 'myendpoint'
16
+ testing_ep.metadata.namespace = 'default'
17
+ testing_ep.subsets = [
18
+ {
19
+ 'addresses' => [{ 'ip' => '172.17.0.25' }],
20
+ 'ports' => [{ 'name' => 'https', 'port' => 6443, 'protocol' => 'TCP' }]
21
+ }
22
+ ]
23
+
24
+ req_body = '{"metadata":{"name":"myendpoint","namespace":"default"},' \
25
+ '"subsets":[{"addresses":[{"ip":"172.17.0.25"}],"ports":[{"name":"https",' \
26
+ '"port":6443,"protocol":"TCP"}]}],"kind":"Endpoints","apiVersion":"v1"}'
27
+
28
+ stub_request(:post, 'http://localhost:8080/api/v1/namespaces/default/endpoints')
29
+ .with(body: req_body)
30
+ .to_return(body: open_test_file('created_endpoint.json'), status: 201)
31
+
32
+ created_ep = client.create_endpoint testing_ep
33
+ assert_equal('Endpoints', created_ep.kind)
34
+ end
35
+ end
@@ -0,0 +1,238 @@
1
+ require 'test_helper'
2
+ require 'vcr'
3
+
4
+ # creation of google's example of guest book
5
+ class CreateGuestbookGo < MiniTest::Test
6
+ def test_create_guestbook_entities
7
+ VCR.configure do |c|
8
+ c.cassette_library_dir = 'test/cassettes'
9
+ c.hook_into :webmock
10
+ end
11
+
12
+ # WebMock.allow_net_connect!
13
+ VCR.use_cassette('kubernetes_guestbook') do # , record: :new_episodes) do
14
+ client = Kubeclient::Client.new 'http://10.35.0.23:8080/api/', 'v1'
15
+
16
+ testing_ns = Kubeclient::Resource.new
17
+ testing_ns.metadata = {}
18
+ testing_ns.metadata.name = 'kubeclient-ns'
19
+
20
+ # delete in case they existed before so creation can be tested
21
+ delete_namespace(client, testing_ns.metadata.name)
22
+ delete_services(
23
+ client, testing_ns.metadata.name,
24
+ ['guestbook', 'redis-master', 'redis-slave']
25
+ )
26
+ delete_replication_controllers(
27
+ client, testing_ns.metadata.name,
28
+ ['guestbook', 'redis-master', 'redis-slave']
29
+ )
30
+
31
+ client.create_namespace testing_ns
32
+ services = create_services(client, testing_ns.metadata.name)
33
+ replicators = create_replication_controllers(client, testing_ns.metadata.name)
34
+
35
+ get_namespaces(client)
36
+ get_services(client, testing_ns.metadata.name)
37
+ get_replication_controllers(client, testing_ns.metadata.name)
38
+
39
+ delete_services(client, testing_ns.metadata.name, services)
40
+ delete_replication_controllers(client, testing_ns.metadata.name, replicators)
41
+
42
+ client.delete_namespace testing_ns.metadata.name
43
+ end
44
+ end
45
+
46
+ def delete_namespace(client, namespace_name)
47
+ client.delete_namespace namespace_name
48
+ rescue KubeException => exception
49
+ assert_instance_of(KubeException, exception)
50
+ assert_equal(404, exception.error_code)
51
+ end
52
+
53
+ def get_namespaces(client)
54
+ namespaces = client.get_namespaces
55
+ assert(true, namespaces.size > 2)
56
+ end
57
+
58
+ def get_services(client, ns)
59
+ retrieved_services = client.get_services(namespace: ns)
60
+ assert_equal(3, retrieved_services.size)
61
+ end
62
+
63
+ def get_replication_controllers(client, ns)
64
+ retrieved_replicators = client.get_replication_controllers(namespace: ns)
65
+ assert_equal(3, retrieved_replicators.size)
66
+ end
67
+
68
+ def create_services(client, ns)
69
+ guestbook_service = client.create_service guestbook_service(ns)
70
+ redis_service = client.create_service redis_service(ns)
71
+ redis_slave_service = client.create_service redis_slave_service(ns)
72
+ [guestbook_service, redis_service, redis_slave_service]
73
+ end
74
+
75
+ def create_replication_controllers(client, namespace)
76
+ rc = client.create_replication_controller guestbook_rc(namespace)
77
+ rc2 = client.create_replication_controller redis_master_rc(namespace)
78
+ rc3 = client.create_replication_controller redis_slave_rc(namespace)
79
+ [rc, rc2, rc3]
80
+ end
81
+
82
+ def delete_services(client, namespace, services)
83
+ # if the entity is not found, no need to fail the test
84
+ services.each do |service|
85
+ begin
86
+ if service.instance_of?(Kubeclient::Service)
87
+ client.delete_service service.metadata.name, namespace
88
+ else
89
+ # it's just a string - service name
90
+ client.delete_service service, namespace
91
+ end
92
+ rescue KubeException => exception
93
+ assert_instance_of(KubeException, exception)
94
+ assert_equal(404, exception.error_code)
95
+ end
96
+ end
97
+ end
98
+
99
+ def delete_replication_controllers(client, namespace, replication_controllers)
100
+ # if the entity is not found, no need to fail the test
101
+ replication_controllers.each do |rc|
102
+ begin
103
+ if rc.instance_of?(Kubeclient::ReplicationController)
104
+ client.delete_replication_controller rc.metadata.name, namespace
105
+ else
106
+ # it's just a string - rc name
107
+ client.delete_replication_controller rc, namespace
108
+ end
109
+ rescue KubeException => exception
110
+ assert_instance_of(KubeException, exception)
111
+ assert_equal(404, exception.error_code)
112
+ end
113
+ end
114
+ end
115
+
116
+ private
117
+
118
+ def construct_base_rc(namespace)
119
+ rc = Kubeclient::ReplicationController.new
120
+ rc.metadata = {}
121
+ rc.metadata.namespace = namespace
122
+ rc.metadata.labels = {}
123
+ rc.spec = {}
124
+ rc.spec.selector = {}
125
+ rc.spec.template = {}
126
+ rc.spec.template.metadata = {}
127
+ rc.spec.template.spec = {}
128
+ rc.spec.template.metadata.labels = {}
129
+ rc
130
+ end
131
+
132
+ def redis_master_rc(namespace)
133
+ rc = construct_base_rc(namespace)
134
+ rc.metadata.name = 'redis-master'
135
+ rc.metadata.labels.app = 'redis'
136
+ rc.metadata.labels.role = 'master'
137
+ rc.spec.replicas = 1
138
+ rc.spec.selector.app = 'redis'
139
+ rc.spec.selector.role = 'master'
140
+ rc.spec.template.metadata.labels.app = 'redis'
141
+ rc.spec.template.metadata.labels.role = 'master'
142
+ rc.spec.template.spec.containers = [{
143
+ 'name' => 'redis-master',
144
+ 'image' => 'redis',
145
+ 'ports' => [{
146
+ 'name' => 'redis-server',
147
+ 'containerPort' => 6379
148
+ }]
149
+ }]
150
+ rc
151
+ end
152
+
153
+ def redis_slave_rc(namespace)
154
+ rc = construct_base_rc(namespace)
155
+ rc.metadata.name = 'redis-slave'
156
+ rc.metadata.labels.app = 'redis'
157
+ rc.metadata.labels.role = 'slave'
158
+ rc.spec.replicas = 2
159
+ rc.spec.selector.app = 'redis'
160
+ rc.spec.selector.role = 'slave'
161
+ rc.spec.template.metadata.labels.app = 'redis'
162
+ rc.spec.template.metadata.labels.role = 'slave'
163
+ rc.spec.template.spec.containers = [{
164
+ 'name' => 'redis-slave',
165
+ 'image' => 'kubernetes/redis-slave:v2',
166
+ 'ports' => [{
167
+ 'name' => 'redis-server',
168
+ 'containerPort' => 6379
169
+ }]
170
+ }]
171
+ rc
172
+ end
173
+
174
+ def guestbook_rc(namespace)
175
+ rc = construct_base_rc(namespace)
176
+ rc.metadata.name = 'guestbook'
177
+ rc.metadata.labels.app = 'guestbook'
178
+ rc.metadata.labels.role = 'slave'
179
+ rc.spec.replicas = 3
180
+ rc.spec.selector.app = 'guestbook'
181
+ rc.spec.template.metadata.labels.app = 'guestbook'
182
+ rc.spec.template.spec.containers = [
183
+ {
184
+ 'name' => 'guestbook',
185
+ 'image' => 'kubernetes/guestbook:v2',
186
+ 'ports' => [
187
+ {
188
+ 'name' => 'http-server',
189
+ 'containerPort' => 3000
190
+ }
191
+ ]
192
+ }
193
+ ]
194
+ rc
195
+ end
196
+
197
+ def base_service(namespace)
198
+ our_service = Kubeclient::Service.new
199
+ our_service.metadata = {}
200
+ our_service.metadata.namespace = namespace
201
+ our_service.metadata.labels = {}
202
+ our_service.spec = {}
203
+ our_service.spec.selector = {}
204
+ our_service
205
+ end
206
+
207
+ def redis_slave_service(namespace)
208
+ our_service = base_service(namespace)
209
+ our_service.metadata.name = 'redis-slave'
210
+ our_service.metadata.labels.app = 'redis'
211
+ our_service.metadata.labels.role = 'slave'
212
+ our_service.spec.ports = [{ 'port' => 6379, 'targetPort' => 'redis-server' }]
213
+ our_service.spec.selector.app = 'redis'
214
+ our_service.spec.selector.role = 'slave'
215
+ our_service
216
+ end
217
+
218
+ def redis_service(namespace)
219
+ our_service = base_service(namespace)
220
+ our_service.metadata.name = 'redis-master'
221
+ our_service.metadata.labels.app = 'redis'
222
+ our_service.metadata.labels.role = 'master'
223
+ our_service.spec.ports = [{ 'port' => 6379, 'targetPort' => 'redis-server' }]
224
+ our_service.spec.selector.app = 'redis'
225
+ our_service.spec.selector.role = 'master'
226
+ our_service
227
+ end
228
+
229
+ def guestbook_service(namespace)
230
+ our_service = base_service(namespace)
231
+ our_service.metadata.name = 'guestbook'
232
+ our_service.metadata.labels.name = 'guestbook'
233
+ our_service.spec.ports = [{ 'port' => 3000, 'targetPort' => 'http-server' }]
234
+ our_service.spec.selector.app = 'guestbook'
235
+ our_service.type = 'LoadBalancer'
236
+ our_service
237
+ end
238
+ end
@@ -0,0 +1,10 @@
1
+ require 'minitest/autorun'
2
+ require 'webmock/minitest'
3
+ require 'json'
4
+ require 'kubeclient'
5
+
6
+ # Assumes test files will be in a subdirectory with the same name as the
7
+ # file suffix. e.g. a file named foo.json would be a "json" subdirectory.
8
+ def open_test_file(name)
9
+ File.new(File.join(File.dirname(__FILE__), name.split('.').last, name))
10
+ end