| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include <functional> |
| #include <memory> |
| |
| #include <gflags/gflags_declare.h> |
| #include <gtest/gtest.h> |
| |
| #include "kudu/consensus/raft_consensus.h" |
| #include "kudu/master/catalog_manager.h" |
| #include "kudu/master/master.h" |
| #include "kudu/master/mini_master.h" |
| #include "kudu/mini-cluster/internal_mini_cluster.h" |
| #include "kudu/rpc/messenger.h" |
| #include "kudu/security/tls_context.h" |
| #include "kudu/security/token_verifier.h" |
| #include "kudu/util/status.h" |
| #include "kudu/util/test_macros.h" |
| #include "kudu/util/test_util.h" |
| |
| DECLARE_bool(enable_leader_failure_detection); |
| |
| using kudu::cluster::InternalMiniCluster; |
| using kudu::cluster::InternalMiniClusterOptions; |
| using kudu::consensus::RaftConsensus; |
| |
| using std::unique_ptr; |
| |
| |
| namespace kudu { |
| |
| class SecurityMasterAuthTest : public KuduTest { |
| public: |
| void SetUp() override { |
| KuduTest::SetUp(); |
| |
| // This test requires manual system catalog leader election. |
| FLAGS_enable_leader_failure_detection = false; |
| |
| InternalMiniClusterOptions opts; |
| opts.num_masters = 5; |
| opts.num_tablet_servers = 0; |
| cluster_.reset(new InternalMiniCluster(env_, opts)); |
| ASSERT_OK(cluster_->Start()); |
| } |
| |
| void TearDown() override { |
| cluster_->Shutdown(); |
| } |
| |
| protected: |
| unique_ptr<InternalMiniCluster> cluster_; |
| }; |
| |
| // This scenario verifies that follower masters get CA-signed certificates |
| // even if they haven't run in the leader role yet. In this particular scenario, |
| // only one of the masters has ever become a leader and the rest have always |
| // been followers. This is a test to cover regressions of KUDU-2265, if any. |
| TEST_F(SecurityMasterAuthTest, FollowerCertificates) { |
| for (auto i = 0; i < cluster_->num_masters(); ++i) { |
| const auto& tls = cluster_->mini_master(i)->master()->tls_context(); |
| // Initially, all master servers have self-signed certs, |
| // but none has CA-signed cert. |
| ASSERT_FALSE(tls.has_signed_cert()); |
| ASSERT_TRUE(tls.has_cert()); |
| } |
| |
| auto consensus = cluster_->mini_master(0)->master()->catalog_manager()->master_consensus(); |
| ASSERT_OK(consensus->StartElection( |
| RaftConsensus::ELECT_EVEN_IF_LEADER_IS_ALIVE, |
| RaftConsensus::EXTERNAL_REQUEST)); |
| |
| // After some time, all masters should have CA-signed certs. |
| ASSERT_EVENTUALLY([&] { |
| for (auto i = 0; i < cluster_->num_masters(); ++i) { |
| const auto& tls = cluster_->mini_master(i)->master()->tls_context(); |
| ASSERT_TRUE(tls.has_signed_cert()); |
| } |
| }); |
| } |
| |
| // This scenario verifies that follower masters get keys for authn token |
| // verification even if they haven't run in the leader role yet. In this |
| // particular scenario, only one of the masters has ever become a leader and |
| // the rest have always been followers. This is a test to cover regressions of |
| // KUDU-2319, if any. |
| TEST_F(SecurityMasterAuthTest, FollowerTokenVerificationKeys) { |
| auto consensus = cluster_->mini_master(0)->master()->catalog_manager()->master_consensus(); |
| ASSERT_OK(consensus->StartElection( |
| RaftConsensus::ELECT_EVEN_IF_LEADER_IS_ALIVE, |
| RaftConsensus::EXTERNAL_REQUEST)); |
| |
| // After some time, all masters should have keys for token verification. |
| ASSERT_EVENTUALLY([&] { |
| for (auto i = 0; i < cluster_->num_masters(); ++i) { |
| const auto& verifier = cluster_->mini_master(i)->master()->messenger()-> |
| token_verifier(); |
| ASSERT_LE(0, verifier.GetMaxKnownKeySequenceNumber()); |
| } |
| }); |
| } |
| |
| } // namespace kudu |