blob: 0559d83d710f4861710bd96fdfef3839103185ed [file] [log] [blame]
//
//
// 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;
}