Parsing the x-envoy-peer-metadata
field.
eg, in istio outbound
{
"args": {},
"headers": {
"Accept-Encoding": "gzip",
"Host": "httpbin.org",
"User-Agent": "Go-http-client/1.1",
"X-Envoy-Attempt-Count": "1",
"X-Envoy-Decorator-Operation": "httpbin.org:443/*",
"X-Envoy-Peer-Metadata": "ChoKCkNMVVNURVJfSUQSDBoKS3ViZXJuZXRlcwp1CgZMQUJFTFMSayppCgwKA2FwcBIFGgNtZHMKKAofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIFGgNtZHMKLwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SCBoGbGF0ZXN0Ch4KBE5BTUUSFhoUbWRzLTZjOGY3ZGM4YjktczJibDYKFQoJTkFNRVNQQUNFEggaBm1kcy1ucwpGCgVPV05FUhI9GjtrdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvbWRzLW5zL2RlcGxveW1lbnRzL21kcwoWCg1XT1JLTE9BRF9OQU1FEgUaA21kcw==",
"X-Envoy-Peer-Metadata-Id": "sidecar~10.244.0.32~mds-6c8f7dc8b9-s2bl6.mds-ns~mds-ns.svc.cluster.local"
},
"origin": "100.15.177.221",
"url": "https://httpbin.org/get"
}
to parse the data above:
$ go run main.go
map[CLUSTER_ID:Kubernetes LABELS:map[app:mds service.istio.io/canonical-name:mds service.istio.io/canonical-revision:latest] NAME:mds-6c8f7dc8b9-s2bl6 NAMESPACE:mds-ns OWNER:kubernetes://apis/apps/v1/namespaces/mds-ns/deployments/mds WORKLOAD_NAME:mds]
a == mds-6c8f7dc8b9-s2bl6
2024-11-10T14:26:10.125198Z info {
"CLUSTER_ID": "Kubernetes",
"LABELS": {
"app": "mds",
"service.istio.io/canonical-name": "mds",
"service.istio.io/canonical-revision": "latest"
},
"NAME": "mds-6c8f7dc8b9-s2bl6",
"NAMESPACE": "mds-ns",
"OWNER": "kubernetes://apis/apps/v1/namespaces/mds-ns/deployments/mds",
"WORKLOAD_NAME": "mds"
}
2024-11-10T14:26:10.125371Z info Name mds-6c8f7dc8b9-s2bl6
2024-11-10T14:26:10.125380Z info CLUSTER_ID Kubernetes
2024-11-10T14:26:10.125384Z info NameSpace mds-ns
2024-11-10T14:26:10.125388Z info OWNER kubernetes://apis/apps/v1/namespaces/mds-ns/deployments/mds
2024-11-10T14:26:10.125393Z info WORKLOAD_NAME mds
2024-11-10T14:26:10.125397Z info app: mds
2024-11-10T14:26:10.125400Z info service.istio.io/canonical-name: mds
2024-11-10T14:26:10.125404Z info service.istio.io/canonical-revision: latest
main.go
:
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"log"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
model "istio.io/istio/pkg/model"
)
var ()
const ()
type configFile struct {
Keys map[string]string `json:"keys"`
}
func main() {
ua := "ChoKCkNMVVNURVJfSUQSDBoKS3ViZXJuZXRlcwp1CgZMQUJFTFMSayppCgwKA2FwcBIFGgNtZHMKKAofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIFGgNtZHMKLwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SCBoGbGF0ZXN0Ch4KBE5BTUUSFhoUbWRzLTZjOGY3ZGM4YjktczJibDYKFQoJTkFNRVNQQUNFEggaBm1kcy1ucwpGCgVPV05FUhI9GjtrdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvbWRzLW5zL2RlcGxveW1lbnRzL21kcwoWCg1XT1JLTE9BRF9OQU1FEgUaA21kcw=="
decodedpeer, err := base64.StdEncoding.DecodeString(ua)
if err != nil {
log.Printf("Error %s", err)
return
}
var s structpb.Struct
err = proto.Unmarshal([]byte(decodedpeer), &s)
if err != nil {
log.Printf("Error %s", err)
return
}
j, err := s.MarshalJSON()
if err != nil {
log.Printf("Error %s", err)
return
}
var anyJson map[string]interface{}
err = json.Unmarshal(j, &anyJson)
if err != nil {
log.Printf("Error %s", err)
return
}
fmt.Printf("%s\n", anyJson)
fmt.Println("a ==", anyJson["NAME"].(string))
var prettyJSON bytes.Buffer
error := json.Indent(&prettyJSON, j, "", "\t")
if error != nil {
log.Printf("Error %s", err)
return
}
log.Println("\n", string(prettyJSON.Bytes()))
// https://github.com/istio/istio/blob/aa93c1f0e74bd9d87bd4a89816d48dc70f867d45/pkg/model/proxy.go#L156C6-L156C27
g := &model.BootstrapNodeMetadata{}
err = json.Unmarshal(j, g)
if err != nil {
fmt.Println("Error:", err)
return
}
log.Printf("Name %s", g.InstanceName)
log.Printf("CLUSTER_ID %s", g.ClusterID)
log.Printf("NameSpace %s", g.Namespace)
log.Printf("OWNER %s", g.Owner)
log.Printf("WORKLOAD_NAME %s", g.WorkloadName)
for i, l := range g.Labels {
log.Printf("%s: %s\n", i, l)
}
}