From 7c27fae77d8f870801b52f1af4f4948038b08912 Mon Sep 17 00:00:00 2001 From: Beni Cherniavsky-Paskin Date: Sun, 20 Mar 2022 13:20:08 +0200 Subject: [PATCH 1/5] test refactor: test_real_cluster.rb --- test/test_real_cluster.rb | 62 +++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/test/test_real_cluster.rb b/test/test_real_cluster.rb index 59c9deb0..568c9374 100644 --- a/test/test_real_cluster.rb +++ b/test/test_real_cluster.rb @@ -16,59 +16,71 @@ def teardown WebMock.disable_net_connect! # Don't allow any connections in other tests. end + # Partially isolated tests that check Client behavior with given `verify_ssl` value: + + # localhost and 127.0.0.1 are among names on the certificate + HOSTNAME_COVERED_BY_CERT = 'https://127.0.0.1:6443'.freeze + # 127.0.0.2 also means localhost but is not included in the certificate. + HOSTNAME_NOT_ON_CERT = 'https://127.0.0.2:6443'.freeze + def test_real_cluster_verify_peer config = Kubeclient::Config.read(config_file('external.kubeconfig')) context = config.context - # localhost and 127.0.0.1 are among names on the certificate client1 = Kubeclient::Client.new( - 'https://127.0.0.1:6443', 'v1', + HOSTNAME_COVERED_BY_CERT, 'v1', ssl_options: context.ssl_options.merge(verify_ssl: OpenSSL::SSL::VERIFY_PEER), auth_options: context.auth_options ) - client1.discover - client1.get_nodes - exercise_watcher_with_timeout(client1.watch_nodes) - # 127.0.0.2 also means localhost but is not included in the certificate. + check_cert_accepted(client1) client2 = Kubeclient::Client.new( - 'https://127.0.0.2:6443', 'v1', + HOSTNAME_NOT_ON_CERT, 'v1', ssl_options: context.ssl_options.merge(verify_ssl: OpenSSL::SSL::VERIFY_PEER), auth_options: context.auth_options ) - # TODO: all OpenSSL exceptions should be wrapped with Kubeclient error. - assert_raises(Kubeclient::HttpError, OpenSSL::SSL::SSLError) do - client2.discover - end - # Since discovery fails, methods like .get_nodes, .watch_nodes would all fail - # on method_missing -> discover. Call lower-level methods to test actual connection. - assert_raises(Kubeclient::HttpError, OpenSSL::SSL::SSLError) do - client2.get_entities('Node', 'nodes', {}) - end - assert_raises(Kubeclient::HttpError, OpenSSL::SSL::SSLError) do - exercise_watcher_with_timeout(client2.watch_entities('nodes')) - end + check_cert_rejected(client2) end def test_real_cluster_verify_none config = Kubeclient::Config.read(config_file('external.kubeconfig')) context = config.context - # localhost and 127.0.0.1 are among names on the certificate client1 = Kubeclient::Client.new( - 'https://127.0.0.1:6443', 'v1', + HOSTNAME_COVERED_BY_CERT, 'v1', ssl_options: context.ssl_options.merge(verify_ssl: OpenSSL::SSL::VERIFY_NONE), auth_options: context.auth_options ) - client1.get_nodes - # 127.0.0.2 also means localhost but is not included in the certificate. + check_cert_accepted(client1) client2 = Kubeclient::Client.new( - 'https://127.0.0.2:6443', 'v1', + HOSTNAME_NOT_ON_CERT, 'v1', ssl_options: context.ssl_options.merge(verify_ssl: OpenSSL::SSL::VERIFY_NONE), auth_options: context.auth_options ) - client2.get_nodes + check_cert_accepted(client2) end private + # Test cert checking on discovery, CRUD, and watch code paths. + def check_cert_accepted(client) + client.discover + client.get_nodes + exercise_watcher_with_timeout(client.watch_nodes) + end + + def check_cert_rejected(client) + # TODO: all OpenSSL exceptions should be wrapped with Kubeclient error. + assert_raises(Kubeclient::HttpError, OpenSSL::SSL::SSLError) do + client.discover + end + # Since discovery fails, methods like .get_nodes, .watch_nodes would all fail + # on method_missing -> discover. Call lower-level methods to test actual connection. + assert_raises(Kubeclient::HttpError, OpenSSL::SSL::SSLError) do + client.get_entities('Node', 'nodes', {}) + end + assert_raises(Kubeclient::HttpError, OpenSSL::SSL::SSLError) do + exercise_watcher_with_timeout(client.watch_entities('nodes')) + end + end + def exercise_watcher_with_timeout(watcher) thread = Thread.new do sleep(1) From 7c331c1cfe87cca54826d74a2f23550006eb1d83 Mon Sep 17 00:00:00 2001 From: Beni Cherniavsky-Paskin Date: Tue, 22 Mar 2022 16:57:26 +0200 Subject: [PATCH 2/5] Tests for concatenated CA data (#460) Test sandwitches the real CA cert between two unrelated CA certs (another-ca1.pem, another-ca2.pem, simply copied from two runs of update_certs_k0s.rb). No test for root+intermediate scenario. Fails before the backport of https://github.com/ManageIQ/kubeclient/pull/461: KubeclientConfigTest#test_concatenated_ca [/home/beni/kubeclient/test/test_config.rb:196]: Expected false to be truthy. (some experimenting with order suggests only first cert is honored.) Passes with the fix. --- test/config/another-ca1.pem | 19 +++++++++ test/config/another-ca2.pem | 19 +++++++++ test/config/concatenated-ca.kubeconfig | 20 +++++++++ test/config/concatenated-ca.pem | 57 ++++++++++++++++++++++++++ test/config/update_certs_k0s.rb | 2 + test/test_config.rb | 6 +++ test/test_real_cluster.rb | 17 ++++++++ 7 files changed, 140 insertions(+) create mode 100644 test/config/another-ca1.pem create mode 100644 test/config/another-ca2.pem create mode 100644 test/config/concatenated-ca.kubeconfig create mode 100644 test/config/concatenated-ca.pem diff --git a/test/config/another-ca1.pem b/test/config/another-ca1.pem new file mode 100644 index 00000000..50825d47 --- /dev/null +++ b/test/config/another-ca1.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAeigAwIBAgIUQZjM/5qoAF78qIDyc+rKi4qBdOIwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAxMNa3ViZXJuZXRlcy1jYTAeFw0yMjAzMjIxNDQzMDBaFw0z +MjAzMTkxNDQzMDBaMBgxFjAUBgNVBAMTDWt1YmVybmV0ZXMtY2EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGkG7g+UjpDhZ7A4Pm7Hme+RWs5IHz4I2X +IclvtO3LuJ26yzz2S8VaXFFeUqzEPb2G1RxFGvoAVN7qrTw0n5MQJCFLAA4dI7oY +8XLRJ7KgTBBIw1jYpgKb2zyHPIJE6VmslliKUiX+QDovdRU/dsbdup2EucrnGw4+ +QNNAc3XMbXgm6lubA6znYZlSpcQ8BKer3tq75q4KUZicIjS6gKQyZjk9a6fcOuCS +ybtlAKp9lYzcwxZkNrx+V1PJMQ1qaJWPnMAVi7Oj5Dm3Jmf1WHBcNEh52Q/0vYlt +4WSaeM5t/Py/m/7c4Ve97f5m2X6EhYyUbzov4qeZOnIJI3MnU1FxAgMBAAGjQjBA +MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSl1qyt +jd96WstRE8h9x5qkCvZUvjANBgkqhkiG9w0BAQsFAAOCAQEAJt55qYvBaniAwvgO +tbO79g1FcQGrxpMX45TuoCE/K+MWDjrr6bp+FbLOqT8MwOsbGwwJIRTHGvkEkVso +5AWI5aSNs3hWnltOdz27ZSHeX77WB4daK1tLK6ggZrp3v9iIpbBwWBFdmAqsPvEs +H17K2BgAzdh6xRKPQd0BGTUpJBfk50R2gDMj7FKyIzBN69IOGytBfAXBhHzEGy4+ +MvtTEIMUjR//KgCrpNeyDuaWHttR5FdnuRxFO7O3BAfyNSaNmd/IEHQf7DIGgzOy ++xWLyH/HRHj5C70qAqjbnrgBODI99BsA9U7oXTuyPLdIboAcFt2zD5DIYgZET52X +53w4jA== +-----END CERTIFICATE----- diff --git a/test/config/another-ca2.pem b/test/config/another-ca2.pem new file mode 100644 index 00000000..53be72e8 --- /dev/null +++ b/test/config/another-ca2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAeigAwIBAgIUHW3OPnmuTquJ0YgbGpmm/blsY2QwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAxMNa3ViZXJuZXRlcy1jYTAeFw0yMjAzMjIxNDQ0MDBaFw0z +MjAzMTkxNDQ0MDBaMBgxFjAUBgNVBAMTDWt1YmVybmV0ZXMtY2EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLMEJs5agS0hNQBxPTtsI6dIhIi/pY8liI +sNukbi5KwKf80FYNyRXqE8ufDVyTFzOc+MG96jnHjDaBWjrVN9On0PgUBo4nPyd4 +DtyvYx2jMzwToSEIo/Z1aroMx1oGywCgdS4/3FWAbhlSbyXKJmhfh6gX0TxWz+dV +zqNuqQq9EWuRhOMg9vgzjfp3mjiPE10lW8pT0j5JT3PI/eGO+C2Z7z33LJXb6GM2 +nXvhGFMGY+7XG65pqJ3L8g1mk+LjPiwyIItw8wPtrnrZ2VXMklMd5Mn+jgCTNe1B +om0nPpPIiTblCr6gcNcVjy5WGN37OKlqrT0JTuSPHcxSUp05LFjDAgMBAAGjQjBA +MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQvV/sB +wbR3UwjkLAMN+6P3fZ/3OjANBgkqhkiG9w0BAQsFAAOCAQEACAk4EQwCkw2EBsSR +2SKoa1SjYFkZzIr/0/TB2YcMUvHF+RpvlD5vQ8/RJjeAl1kc6/niZ9TWCemjBLqI +hPoFe49zr49DyQjC2ZfsXVJvFCr6g7o4q4DtQ6ltyBuTJbkn1hI+aB8zgvpofG44 +mKj18Y7tPvgXtRua4SaeBq777+22AOvKxPied9p4PTrMN4RKTP6+yIbLflej7dBD +zQDjfmmYsH0T2ZRtBpE1dYrUbU3tkizcMZRJBgreoxoff+r5coibMIm/7gh+YoSb +BCItCaeuGSKQ8CJb8DElcPUd6nKUjmeiQL68ztsG/+CXLiL/TZb914VaaCXvPInw +49jJ7w== +-----END CERTIFICATE----- diff --git a/test/config/concatenated-ca.kubeconfig b/test/config/concatenated-ca.kubeconfig new file mode 100644 index 00000000..ed20e4dd --- /dev/null +++ b/test/config/concatenated-ca.kubeconfig @@ -0,0 +1,20 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority: concatenated-ca.pem + server: https://localhost:6443 + name: local +contexts: +- context: + cluster: local + namespace: default + user: user + name: Default +current-context: Default +kind: Config +preferences: {} +users: +- name: user + user: + client-certificate: external-cert.pem + client-key: external-key.rsa diff --git a/test/config/concatenated-ca.pem b/test/config/concatenated-ca.pem new file mode 100644 index 00000000..1117298f --- /dev/null +++ b/test/config/concatenated-ca.pem @@ -0,0 +1,57 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAeigAwIBAgIUQZjM/5qoAF78qIDyc+rKi4qBdOIwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAxMNa3ViZXJuZXRlcy1jYTAeFw0yMjAzMjIxNDQzMDBaFw0z +MjAzMTkxNDQzMDBaMBgxFjAUBgNVBAMTDWt1YmVybmV0ZXMtY2EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGkG7g+UjpDhZ7A4Pm7Hme+RWs5IHz4I2X +IclvtO3LuJ26yzz2S8VaXFFeUqzEPb2G1RxFGvoAVN7qrTw0n5MQJCFLAA4dI7oY +8XLRJ7KgTBBIw1jYpgKb2zyHPIJE6VmslliKUiX+QDovdRU/dsbdup2EucrnGw4+ +QNNAc3XMbXgm6lubA6znYZlSpcQ8BKer3tq75q4KUZicIjS6gKQyZjk9a6fcOuCS +ybtlAKp9lYzcwxZkNrx+V1PJMQ1qaJWPnMAVi7Oj5Dm3Jmf1WHBcNEh52Q/0vYlt +4WSaeM5t/Py/m/7c4Ve97f5m2X6EhYyUbzov4qeZOnIJI3MnU1FxAgMBAAGjQjBA +MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSl1qyt +jd96WstRE8h9x5qkCvZUvjANBgkqhkiG9w0BAQsFAAOCAQEAJt55qYvBaniAwvgO +tbO79g1FcQGrxpMX45TuoCE/K+MWDjrr6bp+FbLOqT8MwOsbGwwJIRTHGvkEkVso +5AWI5aSNs3hWnltOdz27ZSHeX77WB4daK1tLK6ggZrp3v9iIpbBwWBFdmAqsPvEs +H17K2BgAzdh6xRKPQd0BGTUpJBfk50R2gDMj7FKyIzBN69IOGytBfAXBhHzEGy4+ +MvtTEIMUjR//KgCrpNeyDuaWHttR5FdnuRxFO7O3BAfyNSaNmd/IEHQf7DIGgzOy ++xWLyH/HRHj5C70qAqjbnrgBODI99BsA9U7oXTuyPLdIboAcFt2zD5DIYgZET52X +53w4jA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgITPbfpy29aBG67ChRdB6lJegTkmDANBgkqhkiG9w0BAQsF +ADAYMRYwFAYDVQQDEw1rdWJlcm5ldGVzLWNhMB4XDTIyMDIyMTA5MDIwMFoXDTMy +MDIxOTA5MDIwMFowGDEWMBQGA1UEAxMNa3ViZXJuZXRlcy1jYTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMLjZ2cFBalzoimaEcpT9Jz2JmdgsHMOagVd +It7OQpTwDZ3npIICVpguEh9xtovR8m8/HYM+/a4vMQHT+3p8HPjiDaRYGg7OZ9L+ +Fp/9zhBuiaIvg8Z+Bbys9Q9Uuj6VEwfFJBcNH6TmzdiDgQUs5/k+6/vtuJ4ys3sD +KkAOxqPXDaBoANnLpIxdIMQDcWSLFA0wmFhdZJq3KEAoJpEL0WYo1ZRBV3iH77yf +sDbN1OBu2vNnRZ+DrV0ZJ5ApmbFXPX8i4KJaW9lCB62FN0j5XsNDoyTeAVpesfNs +zYufVpBdqNZFkOKg9diMuTMika2aYfDuiVzdebDgcp9aMloKtbECAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBdOiygC +LcuJrq8rNa1xADr5Sp7CMA0GCSqGSIb3DQEBCwUAA4IBAQDCy4IlhASh6Br5XEcI +TpP5ThD1OyRzQnsPe6P1qgWP3kBXK/AcsSl+VGtaZp2oEhJoUnsz7kE8yW3gK+PA +51zY4aHTiF9xkyd5zOCAGB+cfp9Ys+szWzyu0QQ9IBjJ4+eDjg7W0/S+BM2Qn1iL +jTFIe2Bdf+Q/J24/q3ksTXK17UNun14vDRsJgsNcrFt/rumfHPx1ytwsiqKyEKV7 +kFxSwa3d8/AvhGgFpPmfRjU7gAJCFcHz501zhi2a6L5TYBTecVRbqZoeHiZ0YNWI +is5g4VmVB+BxMAM2WEd29v4l/3oI1Pey9rvt7NJqSe1im9uqZgVDeg/vP8zKs/dF +ZYw8 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDADCCAeigAwIBAgIUHW3OPnmuTquJ0YgbGpmm/blsY2QwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAxMNa3ViZXJuZXRlcy1jYTAeFw0yMjAzMjIxNDQ0MDBaFw0z +MjAzMTkxNDQ0MDBaMBgxFjAUBgNVBAMTDWt1YmVybmV0ZXMtY2EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLMEJs5agS0hNQBxPTtsI6dIhIi/pY8liI +sNukbi5KwKf80FYNyRXqE8ufDVyTFzOc+MG96jnHjDaBWjrVN9On0PgUBo4nPyd4 +DtyvYx2jMzwToSEIo/Z1aroMx1oGywCgdS4/3FWAbhlSbyXKJmhfh6gX0TxWz+dV +zqNuqQq9EWuRhOMg9vgzjfp3mjiPE10lW8pT0j5JT3PI/eGO+C2Z7z33LJXb6GM2 +nXvhGFMGY+7XG65pqJ3L8g1mk+LjPiwyIItw8wPtrnrZ2VXMklMd5Mn+jgCTNe1B +om0nPpPIiTblCr6gcNcVjy5WGN37OKlqrT0JTuSPHcxSUp05LFjDAgMBAAGjQjBA +MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQvV/sB +wbR3UwjkLAMN+6P3fZ/3OjANBgkqhkiG9w0BAQsFAAOCAQEACAk4EQwCkw2EBsSR +2SKoa1SjYFkZzIr/0/TB2YcMUvHF+RpvlD5vQ8/RJjeAl1kc6/niZ9TWCemjBLqI +hPoFe49zr49DyQjC2ZfsXVJvFCr6g7o4q4DtQ6ltyBuTJbkn1hI+aB8zgvpofG44 +mKj18Y7tPvgXtRua4SaeBq777+22AOvKxPied9p4PTrMN4RKTP6+yIbLflej7dBD +zQDjfmmYsH0T2ZRtBpE1dYrUbU3tkizcMZRJBgreoxoff+r5coibMIm/7gh+YoSb +BCItCaeuGSKQ8CJb8DElcPUd6nKUjmeiQL68ztsG/+CXLiL/TZb914VaaCXvPInw +49jJ7w== +-----END CERTIFICATE----- diff --git a/test/config/update_certs_k0s.rb b/test/config/update_certs_k0s.rb index 84059bf4..2632d726 100755 --- a/test/config/update_certs_k0s.rb +++ b/test/config/update_certs_k0s.rb @@ -33,6 +33,8 @@ def sh!(*cmd) # The rest could easily be extracted from allinone.kubeconfig, but the test is more robust # if we don't reuse YAML and/or Kubeclient::Config parsing to construct test data. sh! "#{DOCKER} exec #{CONTAINER} cat /var/lib/k0s/pki/ca.crt > test/config/external-ca.pem" +sh! 'cat test/config/another-ca1.pem test/config/external-ca.pem '\ + ' test/config/another-ca2.pem > test/config/concatenated-ca.pem' sh! "#{DOCKER} exec #{CONTAINER} cat /var/lib/k0s/pki/admin.crt > test/config/external-cert.pem" sh! "#{DOCKER} exec #{CONTAINER} cat /var/lib/k0s/pki/admin.key > test/config/external-key.rsa" diff --git a/test/test_config.rb b/test/test_config.rb index 98d2114f..d246624c 100644 --- a/test/test_config.rb +++ b/test/test_config.rb @@ -44,6 +44,12 @@ def test_external_nopath_absolute end end + def test_concatenated_ca + config = Kubeclient::Config.read(config_file('concatenated-ca.kubeconfig')) + assert_equal(['Default'], config.contexts) + check_context(config.context, ssl: true) + end + def test_nouser config = Kubeclient::Config.read(config_file('nouser.kubeconfig')) assert_equal(['default/localhost:6443/nouser'], config.contexts) diff --git a/test/test_real_cluster.rb b/test/test_real_cluster.rb index 568c9374..5c1f4cf9 100644 --- a/test/test_real_cluster.rb +++ b/test/test_real_cluster.rb @@ -57,6 +57,23 @@ def test_real_cluster_verify_none check_cert_accepted(client2) end + def test_real_cluster_concatenated_ca + config = Kubeclient::Config.read(config_file('concatenated-ca.kubeconfig')) + context = config.context + client1 = Kubeclient::Client.new( + HOSTNAME_COVERED_BY_CERT, 'v1', + ssl_options: context.ssl_options.merge(verify_ssl: OpenSSL::SSL::VERIFY_PEER), + auth_options: context.auth_options + ) + check_cert_accepted(client1) + client2 = Kubeclient::Client.new( + HOSTNAME_NOT_ON_CERT, 'v1', + ssl_options: context.ssl_options.merge(verify_ssl: OpenSSL::SSL::VERIFY_PEER), + auth_options: context.auth_options + ) + check_cert_rejected(client2) + end + private # Test cert checking on discovery, CRUD, and watch code paths. From d1cd26d2702d0d74bf19fc9549eefc8ba1bc7ff8 Mon Sep 17 00:00:00 2001 From: Beni Cherniavsky-Paskin Date: Sun, 6 Sep 2020 11:55:48 +0300 Subject: [PATCH 3/5] Merge pull request #461 from PerfectMemory/openssl-x509-store-add-file Load cluster ca certificates using OpenSSL::X509::Store#add_file (cherry picked from commit 53408c10e6f5b39178edec51fbe77b143e2523df) --- lib/kubeclient/config.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/kubeclient/config.rb b/lib/kubeclient/config.rb index 22885908..2520eb6b 100644 --- a/lib/kubeclient/config.rb +++ b/lib/kubeclient/config.rb @@ -51,16 +51,15 @@ def context(context_name = nil) user['exec_result'] = ExecCredentials.run(exec_opts) end - ca_cert_data = fetch_cluster_ca_data(cluster) client_cert_data = fetch_user_cert_data(user) client_key_data = fetch_user_key_data(user) auth_options = fetch_user_auth_options(user) ssl_options = {} - if !ca_cert_data.nil? + if cluster_ca_data?(cluster) cert_store = OpenSSL::X509::Store.new - cert_store.add_cert(OpenSSL::X509::Certificate.new(ca_cert_data)) + populate_cert_store_from_cluster_ca_data(cluster, cert_store) ssl_options[:verify_ssl] = OpenSSL::SSL::VERIFY_PEER ssl_options[:cert_store] = cert_store else @@ -131,11 +130,16 @@ def fetch_context(context_name) [cluster, user, namespace] end - def fetch_cluster_ca_data(cluster) + def cluster_ca_data?(cluster) + cluster.key?('certificate-authority') || cluster.key?('certificate-authority-data') + end + + def populate_cert_store_from_cluster_ca_data(cluster, cert_store) if cluster.key?('certificate-authority') - File.read(ext_file_path(cluster['certificate-authority'])) + cert_store.add_file(ext_file_path(cluster['certificate-authority'])) elsif cluster.key?('certificate-authority-data') - Base64.decode64(cluster['certificate-authority-data']) + ca_cert_data = Base64.decode64(cluster['certificate-authority-data']) + cert_store.add_cert(OpenSSL::X509::Certificate.new(ca_cert_data)) end end From 2dd7f64055575ec48baa48b011215b771f267c44 Mon Sep 17 00:00:00 2001 From: Beni Cherniavsky-Paskin Date: Tue, 22 Mar 2022 17:34:53 +0200 Subject: [PATCH 4/5] Changelog for fix for #460 --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be0fab5d..4d8174eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ Notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). Kubeclient release versioning follows [SemVer](https://semver.org/). +## Unreleased 4.9.z + +### Fixed + +- `Config`: fixed parsing of `certificate-authority` file containing concatenation of + several certificates. Previously, server's cert was checked against only first CA cert, + resulting in possible "certificate verify failed" errors. + + An important use case is a chain of root & intermediate cert(s) - necessary when cluster's CA + itself is signed by another custom CA. + But also helps when you simply concatenate independent certs. (#461, #552) + + - Still broken (#460): inline `certificate-authority-data` is still parsed using `add_cert` + method that handles only one cert. + ## 4.9.2 — 2021-05-30 ### Added From b1824ed8a770ca22aa9520c8e3479c4c84b17f1d Mon Sep 17 00:00:00 2001 From: Beni Cherniavsky-Paskin Date: Wed, 23 Mar 2022 09:45:48 +0200 Subject: [PATCH 5/5] [v4.y] CI: don't abort other builds when one fails error - Helps confirm suspected OS-specific failures. - Normally when one build fails, most other builds already started and some almost complete `bundle install` / started tests. So it's not a big "waste" expensive to let them finish, arguably it's actually a waste to abort them! (sunken cost fallacy? :-) - In case rubocop complains, while I do consider it a merge blocker, it's better contributor (and maintainer) experience to also see test results. --- .github/workflows/actions.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index fd1de5f2..5a74326e 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -10,6 +10,7 @@ on: - '**' jobs: build: + continue-on-error: true runs-on: ${{ matrix.os_and_command.os }} strategy: matrix: