mirror of https://github.com/grpc/grpc.git
[xDS] second attempt: clean up cert provider factory and registry APIs (#33249)
Original was #33226, reverted in #33248.pull/33253/head
parent
8cb7e610c3
commit
52d687ad42
20 changed files with 217 additions and 1084 deletions
@ -1,258 +0,0 @@ |
|||||||
//
|
|
||||||
//
|
|
||||||
// Copyright 2020 gRPC authors.
|
|
||||||
//
|
|
||||||
// Licensed 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 <grpc/support/port_platform.h> |
|
||||||
|
|
||||||
#include "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h" |
|
||||||
|
|
||||||
#include <algorithm> |
|
||||||
|
|
||||||
#include "src/core/lib/iomgr/error.h" |
|
||||||
#include "src/core/lib/json/json_util.h" |
|
||||||
|
|
||||||
namespace grpc_core { |
|
||||||
|
|
||||||
namespace { |
|
||||||
|
|
||||||
const char* kMeshCaPlugin = "meshCA"; |
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
//
|
|
||||||
// GoogleMeshCaCertificateProviderFactory::Config
|
|
||||||
//
|
|
||||||
|
|
||||||
const char* GoogleMeshCaCertificateProviderFactory::Config::name() const { |
|
||||||
return kMeshCaPlugin; |
|
||||||
} |
|
||||||
|
|
||||||
std::string GoogleMeshCaCertificateProviderFactory::Config::ToString() const { |
|
||||||
// TODO(yashykt): To be filled
|
|
||||||
return "{}"; |
|
||||||
} |
|
||||||
|
|
||||||
std::vector<grpc_error_handle> |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectStsService( |
|
||||||
const Json::Object& sts_service) { |
|
||||||
std::vector<grpc_error_handle> error_list_sts_service; |
|
||||||
if (!ParseJsonObjectField(sts_service, "token_exchange_service_uri", |
|
||||||
&sts_config_.token_exchange_service_uri, |
|
||||||
&error_list_sts_service, false)) { |
|
||||||
sts_config_.token_exchange_service_uri = |
|
||||||
"securetoken.googleapis.com"; // default
|
|
||||||
} |
|
||||||
ParseJsonObjectField(sts_service, "resource", &sts_config_.resource, |
|
||||||
&error_list_sts_service, false); |
|
||||||
ParseJsonObjectField(sts_service, "audience", &sts_config_.audience, |
|
||||||
&error_list_sts_service, false); |
|
||||||
if (!ParseJsonObjectField(sts_service, "scope", &sts_config_.scope, |
|
||||||
&error_list_sts_service, false)) { |
|
||||||
sts_config_.scope = |
|
||||||
"https://www.googleapis.com/auth/cloud-platform"; // default
|
|
||||||
} |
|
||||||
ParseJsonObjectField(sts_service, "requested_token_type", |
|
||||||
&sts_config_.requested_token_type, |
|
||||||
&error_list_sts_service, false); |
|
||||||
ParseJsonObjectField(sts_service, "subject_token_path", |
|
||||||
&sts_config_.subject_token_path, |
|
||||||
&error_list_sts_service); |
|
||||||
ParseJsonObjectField(sts_service, "subject_token_type", |
|
||||||
&sts_config_.subject_token_type, |
|
||||||
&error_list_sts_service); |
|
||||||
ParseJsonObjectField(sts_service, "actor_token_path", |
|
||||||
&sts_config_.actor_token_path, &error_list_sts_service, |
|
||||||
false); |
|
||||||
ParseJsonObjectField(sts_service, "actor_token_type", |
|
||||||
&sts_config_.actor_token_type, &error_list_sts_service, |
|
||||||
false); |
|
||||||
return error_list_sts_service; |
|
||||||
} |
|
||||||
|
|
||||||
std::vector<grpc_error_handle> |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectCallCredentials( |
|
||||||
const Json::Object& call_credentials) { |
|
||||||
std::vector<grpc_error_handle> error_list_call_credentials; |
|
||||||
const Json::Object* sts_service = nullptr; |
|
||||||
if (ParseJsonObjectField(call_credentials, "sts_service", &sts_service, |
|
||||||
&error_list_call_credentials)) { |
|
||||||
std::vector<grpc_error_handle> error_list_sts_service = |
|
||||||
ParseJsonObjectStsService(*sts_service); |
|
||||||
if (!error_list_sts_service.empty()) { |
|
||||||
error_list_call_credentials.push_back(GRPC_ERROR_CREATE_FROM_VECTOR( |
|
||||||
"field:sts_service", &error_list_sts_service)); |
|
||||||
} |
|
||||||
} |
|
||||||
return error_list_call_credentials; |
|
||||||
} |
|
||||||
|
|
||||||
std::vector<grpc_error_handle> |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectGoogleGrpc( |
|
||||||
const Json::Object& google_grpc) { |
|
||||||
std::vector<grpc_error_handle> error_list_google_grpc; |
|
||||||
if (!ParseJsonObjectField(google_grpc, "target_uri", &endpoint_, |
|
||||||
&error_list_google_grpc, false)) { |
|
||||||
endpoint_ = "meshca.googleapis.com"; // Default target
|
|
||||||
} |
|
||||||
const Json::Array* call_credentials_array = nullptr; |
|
||||||
if (ParseJsonObjectField(google_grpc, "call_credentials", |
|
||||||
&call_credentials_array, &error_list_google_grpc)) { |
|
||||||
if (call_credentials_array->size() != 1) { |
|
||||||
error_list_google_grpc.push_back(GRPC_ERROR_CREATE( |
|
||||||
"field:call_credentials error:Need exactly one entry.")); |
|
||||||
} else { |
|
||||||
const Json::Object* call_credentials = nullptr; |
|
||||||
if (ExtractJsonType((*call_credentials_array)[0], "call_credentials[0]", |
|
||||||
&call_credentials, &error_list_google_grpc)) { |
|
||||||
std::vector<grpc_error_handle> error_list_call_credentials = |
|
||||||
ParseJsonObjectCallCredentials(*call_credentials); |
|
||||||
if (!error_list_call_credentials.empty()) { |
|
||||||
error_list_google_grpc.push_back(GRPC_ERROR_CREATE_FROM_VECTOR( |
|
||||||
"field:call_credentials", &error_list_call_credentials)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return error_list_google_grpc; |
|
||||||
} |
|
||||||
|
|
||||||
std::vector<grpc_error_handle> |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectGrpcServices( |
|
||||||
const Json::Object& grpc_service) { |
|
||||||
std::vector<grpc_error_handle> error_list_grpc_services; |
|
||||||
const Json::Object* google_grpc = nullptr; |
|
||||||
if (ParseJsonObjectField(grpc_service, "google_grpc", &google_grpc, |
|
||||||
&error_list_grpc_services)) { |
|
||||||
std::vector<grpc_error_handle> error_list_google_grpc = |
|
||||||
ParseJsonObjectGoogleGrpc(*google_grpc); |
|
||||||
if (!error_list_google_grpc.empty()) { |
|
||||||
error_list_grpc_services.push_back(GRPC_ERROR_CREATE_FROM_VECTOR( |
|
||||||
"field:google_grpc", &error_list_google_grpc)); |
|
||||||
} |
|
||||||
} |
|
||||||
if (!ParseJsonObjectFieldAsDuration(grpc_service, "timeout", &timeout_, |
|
||||||
&error_list_grpc_services, false)) { |
|
||||||
timeout_ = Duration::Seconds(10); // 10sec default
|
|
||||||
} |
|
||||||
return error_list_grpc_services; |
|
||||||
} |
|
||||||
|
|
||||||
std::vector<grpc_error_handle> |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectServer( |
|
||||||
const Json::Object& server) { |
|
||||||
std::vector<grpc_error_handle> error_list_server; |
|
||||||
std::string api_type; |
|
||||||
if (ParseJsonObjectField(server, "api_type", &api_type, &error_list_server, |
|
||||||
false)) { |
|
||||||
if (api_type != "GRPC") { |
|
||||||
error_list_server.push_back( |
|
||||||
GRPC_ERROR_CREATE("field:api_type error:Only GRPC is supported")); |
|
||||||
} |
|
||||||
} |
|
||||||
const Json::Array* grpc_services = nullptr; |
|
||||||
if (ParseJsonObjectField(server, "grpc_services", &grpc_services, |
|
||||||
&error_list_server)) { |
|
||||||
if (grpc_services->size() != 1) { |
|
||||||
error_list_server.push_back(GRPC_ERROR_CREATE( |
|
||||||
"field:grpc_services error:Need exactly one entry")); |
|
||||||
} else { |
|
||||||
const Json::Object* grpc_service = nullptr; |
|
||||||
if (ExtractJsonType((*grpc_services)[0], "grpc_services[0]", |
|
||||||
&grpc_service, &error_list_server)) { |
|
||||||
std::vector<grpc_error_handle> error_list_grpc_services = |
|
||||||
ParseJsonObjectGrpcServices(*grpc_service); |
|
||||||
if (!error_list_grpc_services.empty()) { |
|
||||||
error_list_server.push_back(GRPC_ERROR_CREATE_FROM_VECTOR( |
|
||||||
"field:grpc_services", &error_list_grpc_services)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return error_list_server; |
|
||||||
} |
|
||||||
|
|
||||||
RefCountedPtr<GoogleMeshCaCertificateProviderFactory::Config> |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse( |
|
||||||
const Json& config_json, grpc_error_handle* error) { |
|
||||||
auto config = |
|
||||||
MakeRefCounted<GoogleMeshCaCertificateProviderFactory::Config>(); |
|
||||||
if (config_json.type() != Json::Type::kObject) { |
|
||||||
*error = GRPC_ERROR_CREATE("error:config type should be OBJECT."); |
|
||||||
return nullptr; |
|
||||||
} |
|
||||||
std::vector<grpc_error_handle> error_list; |
|
||||||
const Json::Object* server = nullptr; |
|
||||||
if (ParseJsonObjectField(config_json.object(), "server", &server, |
|
||||||
&error_list)) { |
|
||||||
std::vector<grpc_error_handle> error_list_server = |
|
||||||
config->ParseJsonObjectServer(*server); |
|
||||||
if (!error_list_server.empty()) { |
|
||||||
error_list.push_back( |
|
||||||
GRPC_ERROR_CREATE_FROM_VECTOR("field:server", &error_list_server)); |
|
||||||
} |
|
||||||
} |
|
||||||
if (!ParseJsonObjectFieldAsDuration( |
|
||||||
config_json.object(), "certificate_lifetime", |
|
||||||
&config->certificate_lifetime_, &error_list, false)) { |
|
||||||
config->certificate_lifetime_ = Duration::Hours(24); // 24hrs default
|
|
||||||
} |
|
||||||
if (!ParseJsonObjectFieldAsDuration( |
|
||||||
config_json.object(), "renewal_grace_period", |
|
||||||
&config->renewal_grace_period_, &error_list, false)) { |
|
||||||
config->renewal_grace_period_ = Duration::Hours(12); // 12hrs default
|
|
||||||
} |
|
||||||
std::string key_type; |
|
||||||
if (ParseJsonObjectField(config_json.object(), "key_type", &key_type, |
|
||||||
&error_list, false)) { |
|
||||||
if (key_type != "RSA") { |
|
||||||
error_list.push_back( |
|
||||||
GRPC_ERROR_CREATE("field:key_type error:Only RSA is supported.")); |
|
||||||
} |
|
||||||
} |
|
||||||
if (!ParseJsonObjectField(config_json.object(), "key_size", |
|
||||||
&config->key_size_, &error_list, false)) { |
|
||||||
config->key_size_ = 2048; // default 2048 bit key size
|
|
||||||
} |
|
||||||
if (!ParseJsonObjectField(config_json.object(), "location", |
|
||||||
&config->location_, &error_list, false)) { |
|
||||||
// GCE/GKE Metadata server needs to be contacted to get the value.
|
|
||||||
} |
|
||||||
if (!error_list.empty()) { |
|
||||||
*error = GRPC_ERROR_CREATE_FROM_VECTOR( |
|
||||||
"Error parsing google Mesh CA config", &error_list); |
|
||||||
return nullptr; |
|
||||||
} |
|
||||||
return config; |
|
||||||
} |
|
||||||
|
|
||||||
//
|
|
||||||
// GoogleMeshCaCertificateProviderFactory
|
|
||||||
//
|
|
||||||
|
|
||||||
const char* GoogleMeshCaCertificateProviderFactory::name() const { |
|
||||||
return kMeshCaPlugin; |
|
||||||
} |
|
||||||
|
|
||||||
RefCountedPtr<CertificateProviderFactory::Config> |
|
||||||
GoogleMeshCaCertificateProviderFactory::CreateCertificateProviderConfig( |
|
||||||
const Json& config_json, grpc_error_handle* error) { |
|
||||||
return GoogleMeshCaCertificateProviderFactory::Config::Parse(config_json, |
|
||||||
error); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace grpc_core
|
|
@ -1,115 +0,0 @@ |
|||||||
//
|
|
||||||
//
|
|
||||||
// Copyright 2020 gRPC authors.
|
|
||||||
//
|
|
||||||
// Licensed 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.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef GRPC_SRC_CORE_EXT_XDS_GOOGLE_MESH_CA_CERTIFICATE_PROVIDER_FACTORY_H |
|
||||||
#define GRPC_SRC_CORE_EXT_XDS_GOOGLE_MESH_CA_CERTIFICATE_PROVIDER_FACTORY_H |
|
||||||
|
|
||||||
#include <grpc/support/port_platform.h> |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
|
|
||||||
#include <string> |
|
||||||
#include <vector> |
|
||||||
|
|
||||||
#include <grpc/grpc_security.h> |
|
||||||
|
|
||||||
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
||||||
#include "src/core/lib/gprpp/time.h" |
|
||||||
#include "src/core/lib/iomgr/error.h" |
|
||||||
#include "src/core/lib/json/json.h" |
|
||||||
#include "src/core/lib/security/certificate_provider/certificate_provider_factory.h" |
|
||||||
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h" |
|
||||||
|
|
||||||
namespace grpc_core { |
|
||||||
|
|
||||||
class GoogleMeshCaCertificateProviderFactory |
|
||||||
: public CertificateProviderFactory { |
|
||||||
public: |
|
||||||
class Config : public CertificateProviderFactory::Config { |
|
||||||
public: |
|
||||||
struct StsConfig { |
|
||||||
std::string token_exchange_service_uri; |
|
||||||
std::string resource; |
|
||||||
std::string audience; |
|
||||||
std::string scope; |
|
||||||
std::string requested_token_type; |
|
||||||
std::string subject_token_path; |
|
||||||
std::string subject_token_type; |
|
||||||
std::string actor_token_path; |
|
||||||
std::string actor_token_type; |
|
||||||
}; |
|
||||||
|
|
||||||
const char* name() const override; |
|
||||||
|
|
||||||
std::string ToString() const override; |
|
||||||
|
|
||||||
const std::string& endpoint() const { return endpoint_; } |
|
||||||
|
|
||||||
const StsConfig& sts_config() const { return sts_config_; } |
|
||||||
|
|
||||||
Duration timeout() const { return timeout_; } |
|
||||||
|
|
||||||
Duration certificate_lifetime() const { return certificate_lifetime_; } |
|
||||||
|
|
||||||
Duration renewal_grace_period() const { return renewal_grace_period_; } |
|
||||||
|
|
||||||
uint32_t key_size() const { return key_size_; } |
|
||||||
|
|
||||||
const std::string& location() const { return location_; } |
|
||||||
|
|
||||||
static RefCountedPtr<Config> Parse(const Json& config_json, |
|
||||||
grpc_error_handle* error); |
|
||||||
|
|
||||||
private: |
|
||||||
// Helpers for parsing the config
|
|
||||||
std::vector<grpc_error_handle> ParseJsonObjectStsService( |
|
||||||
const Json::Object& sts_service); |
|
||||||
std::vector<grpc_error_handle> ParseJsonObjectCallCredentials( |
|
||||||
const Json::Object& call_credentials); |
|
||||||
std::vector<grpc_error_handle> ParseJsonObjectGoogleGrpc( |
|
||||||
const Json::Object& google_grpc); |
|
||||||
std::vector<grpc_error_handle> ParseJsonObjectGrpcServices( |
|
||||||
const Json::Object& grpc_service); |
|
||||||
std::vector<grpc_error_handle> ParseJsonObjectServer( |
|
||||||
const Json::Object& server); |
|
||||||
|
|
||||||
std::string endpoint_; |
|
||||||
StsConfig sts_config_; |
|
||||||
Duration timeout_; |
|
||||||
Duration certificate_lifetime_; |
|
||||||
Duration renewal_grace_period_; |
|
||||||
uint32_t key_size_; |
|
||||||
std::string location_; |
|
||||||
}; |
|
||||||
|
|
||||||
const char* name() const override; |
|
||||||
|
|
||||||
RefCountedPtr<CertificateProviderFactory::Config> |
|
||||||
CreateCertificateProviderConfig(const Json& config_json, |
|
||||||
grpc_error_handle* error) override; |
|
||||||
|
|
||||||
RefCountedPtr<grpc_tls_certificate_provider> CreateCertificateProvider( |
|
||||||
RefCountedPtr<CertificateProviderFactory::Config> /*config*/) override { |
|
||||||
// TODO(yashykt) : To be implemented
|
|
||||||
return nullptr; |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
} // namespace grpc_core
|
|
||||||
|
|
||||||
#endif // GRPC_SRC_CORE_EXT_XDS_GOOGLE_MESH_CA_CERTIFICATE_PROVIDER_FACTORY_H
|
|
@ -1,367 +0,0 @@ |
|||||||
//
|
|
||||||
//
|
|
||||||
// Copyright 2020 gRPC authors.
|
|
||||||
//
|
|
||||||
// Licensed 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 "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h" |
|
||||||
|
|
||||||
#include "absl/status/status.h" |
|
||||||
#include "absl/status/statusor.h" |
|
||||||
#include "gmock/gmock.h" |
|
||||||
#include "gtest/gtest.h" |
|
||||||
|
|
||||||
#include <grpc/grpc.h> |
|
||||||
|
|
||||||
#include "src/core/lib/gprpp/status_helper.h" |
|
||||||
#include "src/core/lib/gprpp/time.h" |
|
||||||
#include "src/core/lib/json/json_reader.h" |
|
||||||
#include "test/core/util/test_config.h" |
|
||||||
|
|
||||||
namespace grpc_core { |
|
||||||
namespace testing { |
|
||||||
namespace { |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, Basic) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": \"GRPC\"," |
|
||||||
" \"grpc_services\": [{" |
|
||||||
" \"google_grpc\": {" |
|
||||||
" \"target_uri\": \"newmeshca.googleapis.com\"," |
|
||||||
" \"channel_credentials\": { \"google_default\": {}}," |
|
||||||
" \"call_credentials\": [{" |
|
||||||
" \"sts_service\": {" |
|
||||||
" \"token_exchange_service_uri\": " |
|
||||||
"\"newsecuretoken.googleapis.com\"," |
|
||||||
" \"resource\": \"newmeshca.googleapis.com\"," |
|
||||||
" \"audience\": \"newmeshca.googleapis.com\"," |
|
||||||
" \"scope\": " |
|
||||||
"\"https://www.newgoogleapis.com/auth/cloud-platform\"," |
|
||||||
" \"requested_token_type\": " |
|
||||||
"\"urn:ietf:params:oauth:token-type:jwt\"," |
|
||||||
" \"subject_token_path\": \"/etc/secret/sajwt.token\"," |
|
||||||
" \"subject_token_type\": " |
|
||||||
"\"urn:ietf:params:oauth:token-type:jwt\"," |
|
||||||
" \"actor_token_path\": \"/etc/secret/sajwt.token\"," |
|
||||||
" \"actor_token_type\": " |
|
||||||
"\"urn:ietf:params:oauth:token-type:jwt\"" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"timeout\": \"20s\"" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"certificate_lifetime\": \"400s\"," |
|
||||||
" \"renewal_grace_period\": \"100s\"," |
|
||||||
" \"key_type\": \"RSA\"," |
|
||||||
" \"key_size\": 1024," |
|
||||||
" \"location\": " |
|
||||||
"\"https://container.googleapis.com/v1/project/test-project1/locations/" |
|
||||||
"test-zone2/clusters/test-cluster3\"" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
ASSERT_EQ(error, absl::OkStatus()) << StatusToString(error); |
|
||||||
EXPECT_EQ(config->endpoint(), "newmeshca.googleapis.com"); |
|
||||||
EXPECT_EQ(config->sts_config().token_exchange_service_uri, |
|
||||||
"newsecuretoken.googleapis.com"); |
|
||||||
EXPECT_EQ(config->sts_config().resource, "newmeshca.googleapis.com"); |
|
||||||
EXPECT_EQ(config->sts_config().audience, "newmeshca.googleapis.com"); |
|
||||||
EXPECT_EQ(config->sts_config().scope, |
|
||||||
"https://www.newgoogleapis.com/auth/cloud-platform"); |
|
||||||
EXPECT_EQ(config->sts_config().requested_token_type, |
|
||||||
"urn:ietf:params:oauth:token-type:jwt"); |
|
||||||
EXPECT_EQ(config->sts_config().subject_token_path, "/etc/secret/sajwt.token"); |
|
||||||
EXPECT_EQ(config->sts_config().subject_token_type, |
|
||||||
"urn:ietf:params:oauth:token-type:jwt"); |
|
||||||
EXPECT_EQ(config->sts_config().actor_token_path, "/etc/secret/sajwt.token"); |
|
||||||
EXPECT_EQ(config->sts_config().actor_token_type, |
|
||||||
"urn:ietf:params:oauth:token-type:jwt"); |
|
||||||
EXPECT_EQ(config->timeout(), Duration::Seconds(20)); |
|
||||||
EXPECT_EQ(config->certificate_lifetime(), Duration::Seconds(400)); |
|
||||||
EXPECT_EQ(config->renewal_grace_period(), Duration::Seconds(100)); |
|
||||||
EXPECT_EQ(config->key_size(), 1024); |
|
||||||
EXPECT_EQ(config->location(), |
|
||||||
"https://container.googleapis.com/v1/project/test-project1/" |
|
||||||
"locations/test-zone2/clusters/test-cluster3"); |
|
||||||
} |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, Defaults) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": \"GRPC\"," |
|
||||||
" \"grpc_services\": [{" |
|
||||||
" \"google_grpc\": {" |
|
||||||
" \"call_credentials\": [{" |
|
||||||
" \"sts_service\": {" |
|
||||||
" \"scope\": " |
|
||||||
"\"https://www.googleapis.com/auth/cloud-platform\"," |
|
||||||
" \"subject_token_path\": \"/etc/secret/sajwt.token\"," |
|
||||||
" \"subject_token_type\": " |
|
||||||
"\"urn:ietf:params:oauth:token-type:jwt\"" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"location\": " |
|
||||||
"\"https://container.googleapis.com/v1/project/test-project1/locations/" |
|
||||||
"test-zone2/clusters/test-cluster3\"" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
ASSERT_EQ(error, absl::OkStatus()) << StatusToString(error); |
|
||||||
EXPECT_EQ(config->endpoint(), "meshca.googleapis.com"); |
|
||||||
EXPECT_EQ(config->sts_config().token_exchange_service_uri, |
|
||||||
"securetoken.googleapis.com"); |
|
||||||
EXPECT_EQ(config->sts_config().resource, ""); |
|
||||||
EXPECT_EQ(config->sts_config().audience, ""); |
|
||||||
EXPECT_EQ(config->sts_config().scope, |
|
||||||
"https://www.googleapis.com/auth/cloud-platform"); |
|
||||||
EXPECT_EQ(config->sts_config().requested_token_type, ""); |
|
||||||
EXPECT_EQ(config->sts_config().subject_token_path, "/etc/secret/sajwt.token"); |
|
||||||
EXPECT_EQ(config->sts_config().subject_token_type, |
|
||||||
"urn:ietf:params:oauth:token-type:jwt"); |
|
||||||
EXPECT_EQ(config->sts_config().actor_token_path, ""); |
|
||||||
EXPECT_EQ(config->sts_config().actor_token_type, ""); |
|
||||||
EXPECT_EQ(config->timeout(), Duration::Seconds(10)); |
|
||||||
EXPECT_EQ(config->certificate_lifetime(), Duration::Hours(24)); |
|
||||||
EXPECT_EQ(config->renewal_grace_period(), Duration::Hours(12)); |
|
||||||
EXPECT_EQ(config->key_size(), 2048); |
|
||||||
EXPECT_EQ(config->location(), |
|
||||||
"https://container.googleapis.com/v1/project/test-project1/" |
|
||||||
"locations/test-zone2/clusters/test-cluster3"); |
|
||||||
} |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, WrongExpectedValues) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": \"REST\"," |
|
||||||
" \"grpc_services\": [{" |
|
||||||
" \"google_grpc\": {" |
|
||||||
" \"call_credentials\": [{" |
|
||||||
" \"sts_service\": {" |
|
||||||
" \"scope\": " |
|
||||||
"\"https://www.googleapis.com/auth/cloud-platform\"," |
|
||||||
" \"subject_token_path\": \"/etc/secret/sajwt.token\"," |
|
||||||
" \"subject_token_type\": " |
|
||||||
"\"urn:ietf:params:oauth:token-type:jwt\"" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"key_type\": \"DSA\"," |
|
||||||
" \"location\": " |
|
||||||
"\"https://container.googleapis.com/v1/project/test-project1/locations/" |
|
||||||
"test-zone2/clusters/test-cluster3\"" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
EXPECT_THAT( |
|
||||||
StatusToString(error), |
|
||||||
::testing::ContainsRegex("field:api_type error:Only GRPC is supported.*" |
|
||||||
"field:key_type error:Only RSA is supported")); |
|
||||||
} |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, WrongTypes) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": 123," |
|
||||||
" \"grpc_services\": [{" |
|
||||||
" \"google_grpc\": {" |
|
||||||
" \"target_uri\": 123," |
|
||||||
" \"call_credentials\": [{" |
|
||||||
" \"sts_service\": {" |
|
||||||
" \"token_exchange_service_uri\": 123," |
|
||||||
" \"resource\": 123," |
|
||||||
" \"audience\": 123," |
|
||||||
" \"scope\": 123," |
|
||||||
" \"requested_token_type\": 123," |
|
||||||
" \"subject_token_path\": 123," |
|
||||||
" \"subject_token_type\": 123," |
|
||||||
" \"actor_token_path\": 123," |
|
||||||
" \"actor_token_type\": 123" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"timeout\": 20" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"certificate_lifetime\": 400," |
|
||||||
" \"renewal_grace_period\": 100," |
|
||||||
" \"key_type\": 123," |
|
||||||
" \"key_size\": \"1024A\"," |
|
||||||
" \"location\": 123" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
EXPECT_THAT( |
|
||||||
StatusToString(error), |
|
||||||
::testing::ContainsRegex( |
|
||||||
"field:server.*field:api_type error:type should be STRING.*" |
|
||||||
"field:grpc_services.*field:google_grpc.*field:target_uri " |
|
||||||
"error:type should be STRING.*" |
|
||||||
"field:call_credentials.*field:sts_service.*field:token_exchange_" |
|
||||||
"service_uri error:type should be STRING.*" |
|
||||||
"field:resource error:type should be STRING.*" |
|
||||||
"field:audience error:type should be STRING.*" |
|
||||||
"field:scope error:type should be STRING.*" |
|
||||||
"field:requested_token_type error:type should be STRING.*" |
|
||||||
"field:subject_token_path error:type should be STRING.*" |
|
||||||
"field:subject_token_type error:type should be STRING.*" |
|
||||||
"field:actor_token_path error:type should be STRING.*" |
|
||||||
"field:actor_token_type error:type should be STRING.*" |
|
||||||
"field:timeout error:type should be STRING of the form given by " |
|
||||||
"google.proto.Duration.*" |
|
||||||
"field:certificate_lifetime error:type should be STRING of the form " |
|
||||||
"given by google.proto.Duration.*" |
|
||||||
"field:renewal_grace_period error:type should be STRING of the form " |
|
||||||
"given by google.proto.Duration..*" |
|
||||||
"field:key_type error:type should be STRING.*" |
|
||||||
"field:key_size error:failed to parse.*" |
|
||||||
"field:location error:type should be STRING")); |
|
||||||
} |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, GrpcServicesNotAnArray) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": \"GRPC\"," |
|
||||||
" \"grpc_services\": 123" |
|
||||||
" }," |
|
||||||
" \"location\": " |
|
||||||
"\"https://container.googleapis.com/v1/project/test-project1/locations/" |
|
||||||
"test-zone2/clusters/test-cluster3\"" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
EXPECT_THAT( |
|
||||||
StatusToString(error), |
|
||||||
::testing::ContainsRegex( |
|
||||||
"field:server.*field:grpc_services error:type should be ARRAY")); |
|
||||||
} |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, GoogleGrpcNotAnObject) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": \"GRPC\"," |
|
||||||
" \"grpc_services\": [{" |
|
||||||
" \"google_grpc\": 123" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"location\": " |
|
||||||
"\"https://container.googleapis.com/v1/project/test-project1/locations/" |
|
||||||
"test-zone2/clusters/test-cluster3\"" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
EXPECT_THAT( |
|
||||||
StatusToString(error), |
|
||||||
::testing::ContainsRegex("field:server.*field:grpc_services.*field:" |
|
||||||
"google_grpc error:type should be OBJECT")); |
|
||||||
} |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, CallCredentialsNotAnArray) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": \"GRPC\"," |
|
||||||
" \"grpc_services\": [{" |
|
||||||
" \"google_grpc\": {" |
|
||||||
" \"call_credentials\": 123" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"location\": " |
|
||||||
"\"https://container.googleapis.com/v1/project/test-project1/locations/" |
|
||||||
"test-zone2/clusters/test-cluster3\"" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
EXPECT_THAT(StatusToString(error), |
|
||||||
::testing::ContainsRegex( |
|
||||||
"field:server.*field:grpc_services.*field:google_grpc.*" |
|
||||||
"field:call_credentials error:type should be ARRAY")); |
|
||||||
} |
|
||||||
|
|
||||||
TEST(GoogleMeshCaConfigTest, StsServiceNotAnObject) { |
|
||||||
const char* json_str = |
|
||||||
"{" |
|
||||||
" \"server\": {" |
|
||||||
" \"api_type\": \"GRPC\"," |
|
||||||
" \"grpc_services\": [{" |
|
||||||
" \"google_grpc\": {" |
|
||||||
" \"call_credentials\": [{" |
|
||||||
" \"sts_service\": 123" |
|
||||||
" }]" |
|
||||||
" }" |
|
||||||
" }]" |
|
||||||
" }," |
|
||||||
" \"location\": " |
|
||||||
"\"https://container.googleapis.com/v1/project/test-project1/locations/" |
|
||||||
"test-zone2/clusters/test-cluster3\"" |
|
||||||
"}"; |
|
||||||
auto json = JsonParse(json_str); |
|
||||||
ASSERT_TRUE(json.ok()) << json.status(); |
|
||||||
grpc_error_handle error; |
|
||||||
auto config = |
|
||||||
GoogleMeshCaCertificateProviderFactory::Config::Parse(*json, &error); |
|
||||||
EXPECT_THAT( |
|
||||||
StatusToString(error), |
|
||||||
::testing::ContainsRegex( |
|
||||||
"field:server.*field:grpc_services.*field:google_grpc.*field:" |
|
||||||
"call_credentials.*field:sts_service error:type should be OBJECT")); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace
|
|
||||||
} // namespace testing
|
|
||||||
} // namespace grpc_core
|
|
||||||
|
|
||||||
int main(int argc, char** argv) { |
|
||||||
::testing::InitGoogleTest(&argc, argv); |
|
||||||
grpc::testing::TestEnvironment env(&argc, argv); |
|
||||||
grpc_init(); |
|
||||||
auto result = RUN_ALL_TESTS(); |
|
||||||
grpc_shutdown(); |
|
||||||
return result; |
|
||||||
} |
|
Loading…
Reference in new issue