// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package troubleshoot
import (
"context"
"fmt"
"io"
"net/http"
"strings"
envoy_admin_v3 "github.com/envoyproxy/go-control-plane/envoy/admin/v3"
"google.golang.org/protobuf/encoding/protojson"
)
func ( t * Troubleshoot ) request ( path string ) ( [ ] byte , error ) {
client := & http . Client { }
url := fmt . Sprintf ( "http://%v:%s/%s" , t . envoyAddr . IP , t . envoyAdminPort , path )
req , err := http . NewRequest ( "GET" , url , nil )
if err != nil {
return nil , err
}
resp , err := client . Do ( req . WithContext ( context . Background ( ) ) )
if err != nil {
return nil , err
}
if resp != nil {
defer resp . Body . Close ( )
}
if resp != nil && resp . StatusCode == http . StatusNotFound {
return nil , fmt . Errorf ( "ErrBackendNotMounted" )
}
rawConfig , err := io . ReadAll ( resp . Body )
if err != nil {
return nil , err
}
return rawConfig , nil
}
func ( t * Troubleshoot ) GetEnvoyConfigDump ( ) error {
configDumpRaw , err := t . request ( "config_dump" )
if err != nil {
return err
}
config := & envoy_admin_v3 . ConfigDump { }
unmarshal := & protojson . UnmarshalOptions {
DiscardUnknown : true ,
}
err = unmarshal . Unmarshal ( configDumpRaw , config )
if err != nil {
return err
}
t . envoyConfigDump = config
return nil
}
func envoyID ( listenerName string ) string {
parts := strings . Split ( listenerName , ":" )
if parts != nil || len ( parts ) > 0 {
return parts [ 0 ]
}
return ""
}
func ( t * Troubleshoot ) parseClusters ( clusters * envoy_admin_v3 . Clusters ) ( [ ] string , error ) {
upstreams := [ ] string { }
for _ , cs := range clusters . GetClusterStatuses ( ) {
if cs . Name == "local_app" || cs . Name == "local_agent" {
continue
}
upstreams = append ( upstreams , cs . GetName ( ) )
}
return upstreams , nil
}
func ( t * Troubleshoot ) getEnvoyClusters ( ) error {
clustersRaw , err := t . request ( "clusters?format=json" )
if err != nil {
return err
}
clusters := & envoy_admin_v3 . Clusters { }
unmarshal := & protojson . UnmarshalOptions {
DiscardUnknown : true ,
}
err = unmarshal . Unmarshal ( clustersRaw , clusters )
if err != nil {
return err
}
t . envoyClusters = clusters
return nil
}