-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Mixer Client uses Node metadata to populate Mixer attributes #1961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 28 commits
e05a9e5
bda84ae
acfcccc
1bd4e3a
95dc720
8bcdb0c
70139cc
06eba60
f2210ab
f53f6e5
e75a35f
977b7bf
7ed5742
bf0840d
2b2a748
84223fc
a142f1b
f2f9067
37ee3a7
fe42b37
86bb3ee
cf0467c
e32821a
9c245a7
c0b19f2
b83c060
cfd30bf
8d06af7
d9669fc
6817646
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /* Copyright 2018 Istio Authors. All Rights Reserved. | ||
| * | ||
| * 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 ISTIO_UTILS_LOCAL_ATTRIBUTES_H | ||
| #define ISTIO_UTILS_LOCAL_ATTRIBUTES_H | ||
|
|
||
| #include "mixer/v1/attributes.pb.h" | ||
|
|
||
| namespace istio { | ||
| namespace utils { | ||
|
|
||
| struct LocalAttributes { | ||
| // local inbound attributes | ||
| ::istio::mixer::v1::Attributes inbound; | ||
|
|
||
| // local outbound attributes | ||
| ::istio::mixer::v1::Attributes outbound; | ||
|
|
||
| // local forward attributes | ||
| ::istio::mixer::v1::Attributes forward; | ||
| }; | ||
|
|
||
| // LocalNode is abstract information about the node from Mixer's perspective. | ||
| struct LocalNode { | ||
| // like kubernetes://podname.namespace | ||
| std::string uid; | ||
|
|
||
| // namespace | ||
| std::string ns; | ||
| }; | ||
|
|
||
| void CreateLocalAttributes(const LocalNode& local, | ||
| LocalAttributes* local_attributes); | ||
|
|
||
| // create preserialized header to send to proxy that is fronting mixer. | ||
| // This header is used for istio self monitoring. | ||
| bool SerializeForwardedAttributes(const LocalNode& local, | ||
| std::string* serialized_forward_attributes); | ||
|
|
||
| } // namespace utils | ||
| } // namespace istio | ||
|
|
||
| #endif // ISTIO_UTILS_LOCAL_ATTRIBUTES_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,9 +17,16 @@ | |
| #include "src/envoy/utils/grpc_transport.h" | ||
|
|
||
| using ::istio::mixerclient::Statistics; | ||
| using ::istio::utils::AttributeName; | ||
| using ::istio::utils::LocalAttributes; | ||
| using ::istio::utils::LocalNode; | ||
|
|
||
| namespace Envoy { | ||
| namespace Utils { | ||
|
|
||
| const char kNodeUID[] = "NODE_UID"; | ||
| const char kNodeNamespace[] = "NODE_NAMESPACE"; | ||
|
|
||
| namespace { | ||
|
|
||
| // A class to wrap envoy timer for mixer client timer. | ||
|
|
@@ -55,6 +62,18 @@ class EnvoyGrpcAsyncClientFactory : public Grpc::AsyncClientFactory { | |
|
|
||
| } // namespace | ||
|
|
||
| inline bool ReadProtoMap( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move inside anonymous space |
||
| const google::protobuf::Map<std::string, google::protobuf::Value> &meta, | ||
| const std::string &key, std::string *val) { | ||
| const auto it = meta.find(key); | ||
| if (it != meta.end()) { | ||
| *val = it->second.string_value(); | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| // Create all environment functions for mixerclient | ||
| void CreateEnvironment(Event::Dispatcher &dispatcher, | ||
| Runtime::RandomGenerator &random, | ||
|
|
@@ -100,5 +119,79 @@ Grpc::AsyncClientFactoryPtr GrpcClientFactoryForCluster( | |
| return std::make_unique<EnvoyGrpcAsyncClientFactory>(cm, service); | ||
| } | ||
|
|
||
| // This function is for compatibility with existing node ids. | ||
| // "sidecar~10.36.0.15~fortioclient-84469dc8d7-jbbxt.service-graph~service-graph.svc.cluster.local" | ||
| // --> {proxy_type}~{ip}~{node_name}.{node_ns}~{node_domain} | ||
| bool ExtractInfoCompat(const std::string &nodeid, LocalNode *args) { | ||
| auto &logger = Logger::Registry::getLog(Logger::Id::config); | ||
|
|
||
| auto parts = StringUtil::splitToken(nodeid, "~"); | ||
| if (parts.size() < 3) { | ||
| ENVOY_LOG_TO_LOGGER( | ||
| logger, warn, | ||
| "ExtractInfoCompat node id did not have the correct format:", | ||
| "{proxy_type}~{ip}~{node_name}.{node_ns}~{node_domain} ", nodeid); | ||
| return false; | ||
| } | ||
|
|
||
| auto longname = std::string(parts[2].begin(), parts[2].end()); | ||
| auto names = StringUtil::splitToken(longname, "."); | ||
| if (names.size() < 2) { | ||
| ENVOY_LOG_TO_LOGGER(logger, warn, | ||
| "error len(split(longname, '.')) < 3: ", longname); | ||
| return false; | ||
| } | ||
| auto ns = std::string(names[1].begin(), names[1].end()); | ||
|
|
||
| args->ns = ns; | ||
| args->uid = "kubernetes://" + longname; | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| // ExtractInfo depends on NODE_UID, NODE_NAMESPACE | ||
| bool ExtractInfo(const envoy::api::v2::core::Node &node, LocalNode *args) { | ||
| auto &logger = Logger::Registry::getLog(Logger::Id::config); | ||
|
|
||
| const auto meta = node.metadata().fields(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. check if node.has_metadata() first or if node.metadata().fields().empty()
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
|
|
||
| if (meta.empty()) { | ||
| ENVOY_LOG_TO_LOGGER(logger, warn, | ||
| "ExtractInfo metadata empty:", node.DebugString()); | ||
| return false; | ||
| } | ||
|
|
||
| std::string uid; | ||
| if (!ReadProtoMap(meta, kNodeUID, &uid)) { | ||
| ENVOY_LOG_TO_LOGGER(logger, warn, | ||
| "ExtractInfo metadata missing:", kNodeUID, | ||
| node.metadata().DebugString()); | ||
| return false; | ||
| } | ||
|
|
||
| std::string ns; | ||
| if (!ReadProtoMap(meta, kNodeNamespace, &ns)) { | ||
| ENVOY_LOG_TO_LOGGER(logger, warn, | ||
| "ExtractInfo metadata missing:", kNodeNamespace, | ||
| node.metadata().DebugString()); | ||
| return false; | ||
| } | ||
|
|
||
| args->ns = ns; | ||
| args->uid = uid; | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| bool ExtractNodeInfo(const envoy::api::v2::core::Node &node, LocalNode *args) { | ||
| if (ExtractInfo(node, args)) { | ||
| return true; | ||
| } | ||
| if (ExtractInfoCompat(node.id(), args)) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| } // namespace Utils | ||
| } // namespace Envoy | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be nothing envoy specific under istio directory. Maybe get rid of this struct and just create LocalAttributes from envoy node in utils there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LocalNode is a very portable concept. It has the few pieces of information that we need.
It is not evnoy specific.