kubeclient 4.7.0 → 4.12.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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/actions.yml +43 -0
  3. data/.rubocop.yml +111 -14
  4. data/CHANGELOG.md +119 -0
  5. data/README.md +41 -4
  6. data/RELEASING.md +8 -8
  7. data/kubeclient.gemspec +11 -7
  8. data/lib/kubeclient/aws_eks_credentials.rb +17 -8
  9. data/lib/kubeclient/common.rb +55 -21
  10. data/lib/kubeclient/config.rb +33 -13
  11. data/lib/kubeclient/exec_credentials.rb +33 -4
  12. data/lib/kubeclient/version.rb +1 -1
  13. data/lib/kubeclient/watch_stream.rb +1 -0
  14. metadata +46 -222
  15. data/.travis.yml +0 -29
  16. data/test/cassettes/kubernetes_guestbook.yml +0 -879
  17. data/test/config/allinone.kubeconfig +0 -20
  18. data/test/config/execauth.kubeconfig +0 -62
  19. data/test/config/external-ca.pem +0 -18
  20. data/test/config/external-cert.pem +0 -19
  21. data/test/config/external-key.rsa +0 -27
  22. data/test/config/external.kubeconfig +0 -20
  23. data/test/config/gcpauth.kubeconfig +0 -22
  24. data/test/config/gcpcmdauth.kubeconfig +0 -26
  25. data/test/config/nouser.kubeconfig +0 -16
  26. data/test/config/oidcauth.kubeconfig +0 -25
  27. data/test/config/timestamps.kubeconfig +0 -25
  28. data/test/config/userauth.kubeconfig +0 -28
  29. data/test/json/bindings_list.json +0 -10
  30. data/test/json/component_status.json +0 -17
  31. data/test/json/component_status_list.json +0 -52
  32. data/test/json/config.istio.io_api_resource_list.json +0 -679
  33. data/test/json/config_map_list.json +0 -9
  34. data/test/json/core_api_resource_list.json +0 -181
  35. data/test/json/core_api_resource_list_without_kind.json +0 -129
  36. data/test/json/core_oapi_resource_list_without_kind.json +0 -197
  37. data/test/json/created_endpoint.json +0 -28
  38. data/test/json/created_namespace.json +0 -20
  39. data/test/json/created_secret.json +0 -16
  40. data/test/json/created_security_context_constraint.json +0 -65
  41. data/test/json/created_service.json +0 -31
  42. data/test/json/empty_pod_list.json +0 -9
  43. data/test/json/endpoint_list.json +0 -48
  44. data/test/json/entity_list.json +0 -56
  45. data/test/json/event_list.json +0 -35
  46. data/test/json/extensions_v1beta1_api_resource_list.json +0 -217
  47. data/test/json/limit_range.json +0 -23
  48. data/test/json/limit_range_list.json +0 -31
  49. data/test/json/namespace.json +0 -13
  50. data/test/json/namespace_exception.json +0 -8
  51. data/test/json/namespace_list.json +0 -32
  52. data/test/json/node.json +0 -29
  53. data/test/json/node_list.json +0 -37
  54. data/test/json/node_notice.json +0 -160
  55. data/test/json/persistent_volume.json +0 -37
  56. data/test/json/persistent_volume_claim.json +0 -32
  57. data/test/json/persistent_volume_claim_list.json +0 -40
  58. data/test/json/persistent_volume_claims_nil_items.json +0 -8
  59. data/test/json/persistent_volume_list.json +0 -45
  60. data/test/json/pod.json +0 -92
  61. data/test/json/pod_list.json +0 -79
  62. data/test/json/pod_template_list.json +0 -9
  63. data/test/json/pods_1.json +0 -265
  64. data/test/json/pods_2.json +0 -102
  65. data/test/json/pods_410.json +0 -9
  66. data/test/json/processed_template.json +0 -27
  67. data/test/json/replication_controller.json +0 -57
  68. data/test/json/replication_controller_list.json +0 -66
  69. data/test/json/resource_quota.json +0 -46
  70. data/test/json/resource_quota_list.json +0 -54
  71. data/test/json/secret_list.json +0 -44
  72. data/test/json/security.openshift.io_api_resource_list.json +0 -69
  73. data/test/json/security_context_constraint_list.json +0 -375
  74. data/test/json/service.json +0 -33
  75. data/test/json/service_account.json +0 -25
  76. data/test/json/service_account_list.json +0 -82
  77. data/test/json/service_illegal_json_404.json +0 -1
  78. data/test/json/service_json_patch.json +0 -26
  79. data/test/json/service_list.json +0 -97
  80. data/test/json/service_merge_patch.json +0 -26
  81. data/test/json/service_patch.json +0 -25
  82. data/test/json/service_update.json +0 -22
  83. data/test/json/template.json +0 -27
  84. data/test/json/template.openshift.io_api_resource_list.json +0 -75
  85. data/test/json/template_list.json +0 -35
  86. data/test/json/versions_list.json +0 -6
  87. data/test/json/watch_stream.json +0 -3
  88. data/test/test_common.rb +0 -95
  89. data/test/test_component_status.rb +0 -29
  90. data/test/test_config.rb +0 -222
  91. data/test/test_endpoint.rb +0 -54
  92. data/test/test_exec_credentials.rb +0 -125
  93. data/test/test_gcp_command_credentials.rb +0 -27
  94. data/test/test_google_application_default_credentials.rb +0 -15
  95. data/test/test_guestbook_go.rb +0 -235
  96. data/test/test_helper.rb +0 -18
  97. data/test/test_kubeclient.rb +0 -881
  98. data/test/test_limit_range.rb +0 -25
  99. data/test/test_missing_methods.rb +0 -80
  100. data/test/test_namespace.rb +0 -59
  101. data/test/test_node.rb +0 -70
  102. data/test/test_oidc_auth_provider.rb +0 -103
  103. data/test/test_persistent_volume.rb +0 -29
  104. data/test/test_persistent_volume_claim.rb +0 -28
  105. data/test/test_pod.rb +0 -81
  106. data/test/test_pod_log.rb +0 -157
  107. data/test/test_process_template.rb +0 -80
  108. data/test/test_replication_controller.rb +0 -47
  109. data/test/test_resource_list_without_kind.rb +0 -78
  110. data/test/test_resource_quota.rb +0 -23
  111. data/test/test_secret.rb +0 -62
  112. data/test/test_security_context_constraint.rb +0 -62
  113. data/test/test_service.rb +0 -330
  114. data/test/test_service_account.rb +0 -26
  115. data/test/test_watch.rb +0 -195
  116. data/test/txt/pod_log.txt +0 -6
  117. data/test/valid_token_file +0 -1
@@ -1,97 +0,0 @@
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
- }
@@ -1,26 +0,0 @@
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
- "type": "NodePort"
16
- },
17
- "metadata" : {
18
- "name" : "my-service",
19
- "creationTimestamp" : null,
20
- "namespace" : "development",
21
- "resourceVersion" : "2",
22
- "annotations" : {
23
- "key" : "value"
24
- }
25
- }
26
- }
@@ -1,25 +0,0 @@
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
- }
@@ -1,22 +0,0 @@
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
- }
@@ -1,27 +0,0 @@
1
- {
2
- "apiVersion": "template.openshift.io/v1",
3
- "kind": "Template",
4
- "metadata": {
5
- "creationTimestamp": "2018-12-17T16:11:36Z",
6
- "name": "my-template",
7
- "namespace": "default",
8
- "resourceVersion": "21954",
9
- "selfLink": "/apis/template.openshift.io/v1/namespaces/default/templates/my-template",
10
- "uid": "6e03e3e6-0216-11e9-b1e0-68f728fac3ab"
11
- },
12
- "objects": [
13
- {
14
- "apiVersion": "v1",
15
- "kind": "Service",
16
- "metadata": {
17
- "name": "${NAME_PREFIX}my-service"
18
- }
19
- }
20
- ],
21
- "parameters": [
22
- {
23
- "description": "Prefix for names",
24
- "name": "NAME_PREFIX"
25
- }
26
- ]
27
- }
@@ -1,75 +0,0 @@
1
- {
2
- "kind": "APIResourceList",
3
- "apiVersion": "v1",
4
- "groupVersion": "template.openshift.io/v1",
5
- "resources": [
6
- {
7
- "name": "brokertemplateinstances",
8
- "singularName": "",
9
- "namespaced": false,
10
- "kind": "BrokerTemplateInstance",
11
- "verbs": [
12
- "create",
13
- "delete",
14
- "deletecollection",
15
- "get",
16
- "list",
17
- "patch",
18
- "update",
19
- "watch"
20
- ]
21
- },
22
- {
23
- "name": "processedtemplates",
24
- "singularName": "",
25
- "namespaced": true,
26
- "kind": "Template",
27
- "verbs": [
28
- "create"
29
- ]
30
- },
31
- {
32
- "name": "templateinstances",
33
- "singularName": "",
34
- "namespaced": true,
35
- "kind": "TemplateInstance",
36
- "verbs": [
37
- "create",
38
- "delete",
39
- "deletecollection",
40
- "get",
41
- "list",
42
- "patch",
43
- "update",
44
- "watch"
45
- ]
46
- },
47
- {
48
- "name": "templateinstances/status",
49
- "singularName": "",
50
- "namespaced": true,
51
- "kind": "TemplateInstance",
52
- "verbs": [
53
- "get",
54
- "patch",
55
- "update"
56
- ]
57
- },
58
- {
59
- "name": "templates",
60
- "singularName": "",
61
- "namespaced": true,
62
- "kind": "Template",
63
- "verbs": [
64
- "create",
65
- "delete",
66
- "deletecollection",
67
- "get",
68
- "list",
69
- "patch",
70
- "update",
71
- "watch"
72
- ]
73
- }
74
- ]
75
- }
@@ -1,35 +0,0 @@
1
- {
2
- "kind": "TemplateList",
3
- "apiVersion": "template.openshift.io/v1",
4
- "metadata": {
5
- "selfLink": "/apis/template.openshift.io/v1/namespaces/default/templates",
6
- "resourceVersion": "22758"
7
- },
8
- "items": [
9
- {
10
- "metadata": {
11
- "name": "my-template",
12
- "namespace": "default",
13
- "selfLink": "/apis/template.openshift.io/v1/namespaces/default/templates/my-template",
14
- "uid": "6e03e3e6-0216-11e9-b1e0-68f728fac3ab",
15
- "resourceVersion": "21954",
16
- "creationTimestamp": "2018-12-17T16:11:36Z"
17
- },
18
- "objects": [
19
- {
20
- "apiVersion": "v1",
21
- "kind": "Service",
22
- "metadata": {
23
- "name": "${NAME_PREFIX}my-service"
24
- }
25
- }
26
- ],
27
- "parameters": [
28
- {
29
- "name": "NAME_PREFIX",
30
- "description": "Prefix for names"
31
- }
32
- ]
33
- }
34
- ]
35
- }
@@ -1,6 +0,0 @@
1
- {
2
- "versions": [
3
- "v1beta3",
4
- "v1"
5
- ]
6
- }
@@ -1,3 +0,0 @@
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"}}}
data/test/test_common.rb DELETED
@@ -1,95 +0,0 @@
1
-
2
- require_relative 'test_helper'
3
-
4
- # Unit tests for the common module
5
- class CommonTest < MiniTest::Test
6
- class ClientStub
7
- include Kubeclient::ClientMixin
8
- end
9
-
10
- def client
11
- @client ||= ClientStub.new
12
- end
13
-
14
- def test_underscore_entity
15
- %w[
16
- Pod pod
17
- Service service
18
- ReplicationController replication_controller
19
- Node node
20
- Event event
21
- Endpoint endpoint
22
- Namespace namespace
23
- Secret secret
24
- ResourceQuota resource_quota
25
- LimitRange limit_range
26
- PersistentVolume persistent_volume
27
- PersistentVolumeClaim persistent_volume_claim
28
- ComponentStatus component_status
29
- ServiceAccount service_account
30
- Project project
31
- Route route
32
- ClusterRoleBinding cluster_role_binding
33
- Build build
34
- BuildConfig build_config
35
- Image image
36
- ImageStream image_stream
37
- dogstatsd dogstatsd
38
- lowerCamelUPPERCase lower_camel_uppercase
39
- HTTPAPISpecBinding httpapispec_binding
40
- APIGroup apigroup
41
- APIGroupList apigroup_list
42
- APIResourceList apiresource_list
43
- APIService apiservice
44
- APIServiceList apiservice_list
45
- APIVersions apiversions
46
- OAuthAccessToken oauth_access_token
47
- OAuthAccessTokenList oauth_access_token_list
48
- OAuthAuthorizeToken oauth_authorize_token
49
- OAuthAuthorizeTokenList oauth_authorize_token_list
50
- OAuthClient oauth_client
51
- OAuthClientAuthorization oauth_client_authorization
52
- OAuthClientAuthorizationList oauth_client_authorization_list
53
- OAuthClientList oauth_client_list
54
- ].each_slice(2) do |kind, expected_underscore|
55
- underscore = Kubeclient::ClientMixin.underscore_entity(kind)
56
- assert_equal(underscore, expected_underscore)
57
- end
58
- end
59
-
60
- def test_format_datetime_with_string
61
- value = '2018-04-27T18:30:17.480321984Z'
62
- formatted = client.send(:format_datetime, value)
63
- assert_equal(formatted, value)
64
- end
65
-
66
- def test_format_datetime_with_datetime
67
- value = DateTime.new(2018, 4, 30, 19, 20, 33)
68
- formatted = client.send(:format_datetime, value)
69
- assert_equal(formatted, '2018-04-30T19:20:33.000000000+00:00')
70
- end
71
-
72
- def test_format_datetime_with_time
73
- value = Time.new(2018, 4, 30, 19, 20, 33, 0)
74
- formatted = client.send(:format_datetime, value)
75
- assert_equal(formatted, '2018-04-30T19:20:33.000000000+00:00')
76
- end
77
-
78
- def test_parse_definition_with_unconventional_names
79
- %w[
80
- PluralPolicy pluralpolicies plural_policy plural_policies
81
- LatinDatum latindata latin_datum latin_data
82
- Noseparator noseparators noseparator noseparators
83
- lowercase lowercases lowercase lowercases
84
- TestWithDash test-with-dashes test_with_dash test_with_dashes
85
- TestUnderscore test_underscores test_underscore test_underscores
86
- TestMismatch other-odd-name testmismatch otheroddname
87
- MixedDashMinus mixed-dash_minuses mixed_dash_minus mixed_dash_minuses
88
- SameUptoWordboundary sameup-toword-boundarys sameuptowordboundary sameuptowordboundarys
89
- ].each_slice(4) do |kind, plural, expected_single, expected_plural|
90
- method_names = Kubeclient::ClientMixin.parse_definition(kind, plural).method_names
91
- assert_equal(method_names[0], expected_single)
92
- assert_equal(method_names[1], expected_plural)
93
- end
94
- end
95
- end
@@ -1,29 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- # ComponentStatus tests
4
- class TestComponentStatus < MiniTest::Test
5
- def test_get_from_json_v3
6
- stub_core_api_list
7
- stub_request(:get, %r{/componentstatuses})
8
- .to_return(body: open_test_file('component_status.json'), status: 200)
9
-
10
- client = Kubeclient::Client.new('http://localhost:8080/api/', 'v1')
11
- component_status = client.get_component_status('etcd-0', 'default')
12
-
13
- assert_instance_of(Kubeclient::Resource, component_status)
14
- assert_equal('etcd-0', component_status.metadata.name)
15
- assert_equal('Healthy', component_status.conditions[0].type)
16
- assert_equal('True', component_status.conditions[0].status)
17
-
18
- assert_requested(
19
- :get,
20
- 'http://localhost:8080/api/v1',
21
- times: 1
22
- )
23
- assert_requested(
24
- :get,
25
- 'http://localhost:8080/api/v1/namespaces/default/componentstatuses/etcd-0',
26
- times: 1
27
- )
28
- end
29
- end
data/test/test_config.rb DELETED
@@ -1,222 +0,0 @@
1
- require_relative 'test_helper'
2
- require 'yaml'
3
- require 'open3'
4
-
5
- # Testing Kubernetes client configuration
6
- class KubeclientConfigTest < MiniTest::Test
7
- def test_allinone
8
- config = Kubeclient::Config.read(config_file('allinone.kubeconfig'))
9
- assert_equal(['default/localhost:8443/system:admin'], config.contexts)
10
- check_context(config.context, ssl: true)
11
- end
12
-
13
- def test_external
14
- config = Kubeclient::Config.read(config_file('external.kubeconfig'))
15
- assert_equal(['default/localhost:8443/system:admin'], config.contexts)
16
- check_context(config.context, ssl: true)
17
- end
18
-
19
- def test_allinone_nopath
20
- yaml = File.read(config_file('allinone.kubeconfig'))
21
- # A self-contained config shouldn't depend on kcfg_path.
22
- config = Kubeclient::Config.new(YAML.safe_load(yaml), nil)
23
- assert_equal(['default/localhost:8443/system:admin'], config.contexts)
24
- check_context(config.context, ssl: true)
25
- end
26
-
27
- def test_external_nopath
28
- yaml = File.read(config_file('external.kubeconfig'))
29
- # kcfg_path = nil should prevent file access
30
- config = Kubeclient::Config.new(YAML.safe_load(yaml), nil)
31
- assert_raises(StandardError) do
32
- config.context
33
- end
34
- end
35
-
36
- def test_external_nopath_absolute
37
- yaml = File.read(config_file('external.kubeconfig'))
38
- # kcfg_path = nil should prevent file access, even if absolute path specified
39
- ca_absolute_path = File.absolute_path(config_file('external-'))
40
- yaml = yaml.gsub('external-', ca_absolute_path)
41
- config = Kubeclient::Config.new(YAML.safe_load(yaml), nil)
42
- assert_raises(StandardError) do
43
- config.context
44
- end
45
- end
46
-
47
- def test_nouser
48
- config = Kubeclient::Config.read(config_file('nouser.kubeconfig'))
49
- assert_equal(['default/localhost:8443/nouser'], config.contexts)
50
- check_context(config.context, ssl: false)
51
- end
52
-
53
- def test_user_token
54
- config = Kubeclient::Config.read(config_file('userauth.kubeconfig'))
55
- assert_equal(['localhost/system:admin:token', 'localhost/system:admin:userpass'],
56
- config.contexts)
57
- context = config.context('localhost/system:admin:token')
58
- check_context(context, ssl: false)
59
- assert_equal('0123456789ABCDEF0123456789ABCDEF', context.auth_options[:bearer_token])
60
- end
61
-
62
- def test_user_password
63
- config = Kubeclient::Config.read(config_file('userauth.kubeconfig'))
64
- assert_equal(['localhost/system:admin:token', 'localhost/system:admin:userpass'],
65
- config.contexts)
66
- context = config.context('localhost/system:admin:userpass')
67
- check_context(context, ssl: false)
68
- assert_equal('admin', context.auth_options[:username])
69
- assert_equal('pAssw0rd123', context.auth_options[:password])
70
- end
71
-
72
- def test_timestamps
73
- # Test YAML parsing doesn't crash on YAML timestamp syntax.
74
- Kubeclient::Config.read(config_file('timestamps.kubeconfig'))
75
- end
76
-
77
- def test_user_exec
78
- token = '0123456789ABCDEF0123456789ABCDEF'
79
- creds = {
80
- 'apiVersion': 'client.authentication.k8s.io/v1beta1',
81
- 'status': {
82
- 'token': token
83
- }
84
- }
85
-
86
- config = Kubeclient::Config.read(config_file('execauth.kubeconfig'))
87
- assert_equal(['localhost/system:admin:exec-search-path',
88
- 'localhost/system:admin:exec-relative-path',
89
- 'localhost/system:admin:exec-absolute-path'],
90
- config.contexts)
91
-
92
- # A bare command name in config means search PATH, so it's executed as bare command.
93
- stub_exec(%r{^example-exec-plugin$}, creds) do
94
- context = config.context('localhost/system:admin:exec-search-path')
95
- check_context(context, ssl: false)
96
- assert_equal(token, context.auth_options[:bearer_token])
97
- end
98
-
99
- # A relative path is taken relative to the dir of the kubeconfig.
100
- stub_exec(%r{.*config/dir/example-exec-plugin$}, creds) do
101
- context = config.context('localhost/system:admin:exec-relative-path')
102
- check_context(context, ssl: false)
103
- assert_equal(token, context.auth_options[:bearer_token])
104
- end
105
-
106
- # An absolute path is taken as-is.
107
- stub_exec(%r{^/abs/path/example-exec-plugin$}, creds) do
108
- context = config.context('localhost/system:admin:exec-absolute-path')
109
- check_context(context, ssl: false)
110
- assert_equal(token, context.auth_options[:bearer_token])
111
- end
112
- end
113
-
114
- def test_user_exec_nopath
115
- yaml = File.read(config_file('execauth.kubeconfig'))
116
- config = Kubeclient::Config.new(YAML.safe_load(yaml), nil)
117
- config.contexts.each do |context_name|
118
- Open3.stub(:capture3, proc { flunk 'should not execute command' }) do
119
- assert_raises(StandardError) do
120
- config.context(context_name)
121
- end
122
- end
123
- end
124
- end
125
-
126
- def test_gcp_default_auth
127
- Kubeclient::GoogleApplicationDefaultCredentials.expects(:token).returns('token1').once
128
- parsed = YAML.safe_load(File.read(config_file('gcpauth.kubeconfig')), [Date, Time])
129
- config = Kubeclient::Config.new(parsed, nil)
130
- config.context(config.contexts.first)
131
- end
132
-
133
- # Each call to .context() obtains a new token, calling .auth_options doesn't change anything.
134
- # NOTE: this is not a guarantee, may change, just testing current behavior.
135
- def test_gcp_default_auth_renew
136
- Kubeclient::GoogleApplicationDefaultCredentials.expects(:token).returns('token1').once
137
- parsed = YAML.safe_load(File.read(config_file('gcpauth.kubeconfig')), [Date, Time])
138
- config = Kubeclient::Config.new(parsed, nil)
139
- context = config.context(config.contexts.first)
140
- assert_equal({ bearer_token: 'token1' }, context.auth_options)
141
- assert_equal({ bearer_token: 'token1' }, context.auth_options)
142
-
143
- Kubeclient::GoogleApplicationDefaultCredentials.expects(:token).returns('token2').once
144
- context2 = config.context(config.contexts.first)
145
- assert_equal({ bearer_token: 'token2' }, context2.auth_options)
146
- assert_equal({ bearer_token: 'token1' }, context.auth_options)
147
- end
148
-
149
- def test_gcp_command_auth
150
- Kubeclient::GCPCommandCredentials.expects(:token)
151
- .with('access-token' => '<fake_token>',
152
- 'cmd-args' => 'config config-helper --format=json',
153
- 'cmd-path' => '/path/to/gcloud',
154
- 'expiry' => '2019-04-09 19:26:18 UTC',
155
- 'expiry-key' => '{.credential.token_expiry}',
156
- 'token-key' => '{.credential.access_token}')
157
- .returns('token1')
158
- .once
159
- config = Kubeclient::Config.read(config_file('gcpcmdauth.kubeconfig'))
160
- config.context(config.contexts.first)
161
- end
162
-
163
- def test_oidc_auth_provider
164
- Kubeclient::OIDCAuthProvider.expects(:token)
165
- .with('client-id' => 'fake-client-id',
166
- 'client-secret' => 'fake-client-secret',
167
- 'id-token' => 'fake-id-token',
168
- 'idp-issuer-url' => 'https://accounts.google.com',
169
- 'refresh-token' => 'fake-refresh-token')
170
- .returns('token1')
171
- .once
172
- parsed = YAML.safe_load(File.read(config_file('oidcauth.kubeconfig')))
173
- config = Kubeclient::Config.new(parsed, nil)
174
- config.context(config.contexts.first)
175
- end
176
-
177
- private
178
-
179
- def check_context(context, ssl: true)
180
- assert_equal('https://localhost:8443', context.api_endpoint)
181
- assert_equal('v1', context.api_version)
182
- assert_equal('default', context.namespace)
183
- if ssl
184
- assert_equal(OpenSSL::SSL::VERIFY_PEER, context.ssl_options[:verify_ssl])
185
- assert_kind_of(OpenSSL::X509::Store, context.ssl_options[:cert_store])
186
- assert_kind_of(OpenSSL::X509::Certificate, context.ssl_options[:client_cert])
187
- assert_kind_of(OpenSSL::PKey::RSA, context.ssl_options[:client_key])
188
- # When certificates expire the quickest way to recreate them is using
189
- # an OpenShift tool (100% compatible with kubernetes):
190
- #
191
- # $ oc adm ca create-master-certs --hostnames=localhost
192
- #
193
- # At the time of this writing the files to be updated are:
194
- #
195
- # cp openshift.local.config/master/admin.kubeconfig test/config/allinone.kubeconfig
196
- # cp openshift.local.config/master/ca.crt test/config/external-ca.pem
197
- # cp openshift.local.config/master/admin.crt test/config/external-cert.pem
198
- # cp openshift.local.config/master/admin.key test/config/external-key.rsa
199
- assert(context.ssl_options[:cert_store].verify(context.ssl_options[:client_cert]))
200
- else
201
- assert_equal(OpenSSL::SSL::VERIFY_NONE, context.ssl_options[:verify_ssl])
202
- end
203
- end
204
-
205
- def config_file(name)
206
- File.join(File.dirname(__FILE__), 'config', name)
207
- end
208
-
209
- def stub_exec(command_regexp, creds)
210
- st = Minitest::Mock.new
211
- st.expect(:success?, true)
212
-
213
- capture3_stub = lambda do |_env, command, *_args|
214
- assert_match command_regexp, command
215
- [JSON.dump(creds), nil, st]
216
- end
217
-
218
- Open3.stub(:capture3, capture3_stub) do
219
- yield
220
- end
221
- end
222
- end