...

Source file src/github.com/linkerd/linkerd2/viz/tap/pkg/requests.go

Documentation: github.com/linkerd/linkerd2/viz/tap/pkg

     1  package pkg
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/linkerd/linkerd2/pkg/k8s"
     7  	metricsPb "github.com/linkerd/linkerd2/viz/metrics-api/gen/viz"
     8  	"github.com/linkerd/linkerd2/viz/pkg/util"
     9  	tapPb "github.com/linkerd/linkerd2/viz/tap/gen/tap"
    10  )
    11  
    12  // ValidTapDestinations specifies resource types allowed as a tap destination:
    13  // - destination resource on an outbound 'to' query
    14  var ValidTapDestinations = []string{
    15  	k8s.CronJob,
    16  	k8s.DaemonSet,
    17  	k8s.Deployment,
    18  	k8s.Job,
    19  	k8s.Namespace,
    20  	k8s.Pod,
    21  	k8s.ReplicaSet,
    22  	k8s.ReplicationController,
    23  	k8s.Service,
    24  	k8s.StatefulSet,
    25  }
    26  
    27  // TapRequestParams contains parameters that are used to build a
    28  // TapByResourceRequest.
    29  type TapRequestParams struct {
    30  	Resource      string
    31  	Namespace     string
    32  	ToResource    string
    33  	ToNamespace   string
    34  	MaxRps        float32
    35  	Scheme        string
    36  	Method        string
    37  	Authority     string
    38  	Path          string
    39  	Extract       bool
    40  	LabelSelector string
    41  }
    42  
    43  // BuildTapByResourceRequest builds a Public API TapByResourceRequest from a
    44  // TapRequestParams.
    45  func BuildTapByResourceRequest(params TapRequestParams) (*tapPb.TapByResourceRequest, error) {
    46  	target, err := util.BuildResource(params.Namespace, params.Resource)
    47  	if err != nil {
    48  		return nil, fmt.Errorf("target resource invalid: %w", err)
    49  	}
    50  	if !contains(util.ValidTargets, target.Type) {
    51  		return nil, fmt.Errorf("unsupported resource type [%s]", target.Type)
    52  	}
    53  
    54  	matches := []*tapPb.TapByResourceRequest_Match{}
    55  
    56  	if params.ToResource != "" {
    57  		destination, err := util.BuildResource(params.ToNamespace, params.ToResource)
    58  		if err != nil {
    59  			return nil, fmt.Errorf("destination resource invalid: %w", err)
    60  		}
    61  		if !contains(ValidTapDestinations, destination.Type) {
    62  			return nil, fmt.Errorf("unsupported resource type [%s]", destination.Type)
    63  		}
    64  
    65  		match := tapPb.TapByResourceRequest_Match{
    66  			Match: &tapPb.TapByResourceRequest_Match_Destinations{
    67  				Destinations: &metricsPb.ResourceSelection{
    68  					Resource: destination,
    69  				},
    70  			},
    71  		}
    72  		matches = append(matches, &match)
    73  	}
    74  
    75  	if params.Scheme != "" {
    76  		match := buildMatchHTTP(&tapPb.TapByResourceRequest_Match_Http{
    77  			Match: &tapPb.TapByResourceRequest_Match_Http_Scheme{Scheme: params.Scheme},
    78  		})
    79  		matches = append(matches, &match)
    80  	}
    81  	if params.Method != "" {
    82  		match := buildMatchHTTP(&tapPb.TapByResourceRequest_Match_Http{
    83  			Match: &tapPb.TapByResourceRequest_Match_Http_Method{Method: params.Method},
    84  		})
    85  		matches = append(matches, &match)
    86  	}
    87  	if params.Authority != "" {
    88  		match := buildMatchHTTP(&tapPb.TapByResourceRequest_Match_Http{
    89  			Match: &tapPb.TapByResourceRequest_Match_Http_Authority{Authority: params.Authority},
    90  		})
    91  		matches = append(matches, &match)
    92  	}
    93  	if params.Path != "" {
    94  		match := buildMatchHTTP(&tapPb.TapByResourceRequest_Match_Http{
    95  			Match: &tapPb.TapByResourceRequest_Match_Http_Path{Path: params.Path},
    96  		})
    97  		matches = append(matches, &match)
    98  	}
    99  
   100  	extract := &tapPb.TapByResourceRequest_Extract{}
   101  	if params.Extract {
   102  		extract = buildExtractHTTP(&tapPb.TapByResourceRequest_Extract_Http{
   103  			Extract: &tapPb.TapByResourceRequest_Extract_Http_Headers_{
   104  				Headers: &tapPb.TapByResourceRequest_Extract_Http_Headers{},
   105  			},
   106  		})
   107  	}
   108  
   109  	return &tapPb.TapByResourceRequest{
   110  		Target: &metricsPb.ResourceSelection{
   111  			Resource:      target,
   112  			LabelSelector: params.LabelSelector,
   113  		},
   114  		MaxRps: params.MaxRps,
   115  		Match: &tapPb.TapByResourceRequest_Match{
   116  			Match: &tapPb.TapByResourceRequest_Match_All{
   117  				All: &tapPb.TapByResourceRequest_Match_Seq{
   118  					Matches: matches,
   119  				},
   120  			},
   121  		},
   122  		Extract: extract,
   123  	}, nil
   124  }
   125  
   126  func buildMatchHTTP(match *tapPb.TapByResourceRequest_Match_Http) tapPb.TapByResourceRequest_Match {
   127  	return tapPb.TapByResourceRequest_Match{
   128  		Match: &tapPb.TapByResourceRequest_Match_Http_{
   129  			Http: match,
   130  		},
   131  	}
   132  }
   133  
   134  func buildExtractHTTP(extract *tapPb.TapByResourceRequest_Extract_Http) *tapPb.TapByResourceRequest_Extract {
   135  	return &tapPb.TapByResourceRequest_Extract{
   136  		Extract: &tapPb.TapByResourceRequest_Extract_Http_{
   137  			Http: extract,
   138  		},
   139  	}
   140  }
   141  
   142  func contains(list []string, s string) bool {
   143  	for _, elem := range list {
   144  		if s == elem {
   145  			return true
   146  		}
   147  	}
   148  	return false
   149  }
   150  

View as plain text