mirror of https://github.com/linkerd/linkerd2.git
Enable lint check for comments (#2023)
Commit 1: Enable lint check for comments Part of #217. Follow up from #1982 and #2018. A subsequent commit will fix the ci failure. Commit 2: Address all comment-related linter errors. This change addresses all comment-related linter errors by doing the following: - Add comments to exported symbols - Make some exported symbols private - Recommend via TODOs that some exported symbols should should move or be removed This PR does not: - Modify, move, or remove any code - Modify existing comments Signed-off-by: Andrew Seigner <siggy@buoyant.io>
This commit is contained in:
parent
ef02cd6828
commit
1c302182ef
4
bin/lint
4
bin/lint
|
@ -12,8 +12,8 @@ cd "$rootdir"
|
|||
# install golint from vendor
|
||||
go install ./vendor/golang.org/x/lint/golint
|
||||
|
||||
# use `go list` to exclude packages in vendor, ignore uncommented warnings
|
||||
out=$(go list ./... | xargs golint | grep -v 'should have comment') || true
|
||||
# use `go list` to exclude packages in vendor
|
||||
out=$(go list ./... | xargs golint) || true
|
||||
|
||||
if [ -n "$out" ]; then
|
||||
echo "$out"
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// NewClient creates a new gRPC client to the Destination service.
|
||||
// TODO: consider moving this into destination-client, or removing altogether.
|
||||
func NewClient(addr string) (pb.DestinationClient, *grpc.ClientConn, error) {
|
||||
conn, err := grpc.Dial(addr, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
|
|
|
@ -190,6 +190,8 @@ func newClient(apiURL *url.URL, httpClientToUse *http.Client, controlPlaneNamesp
|
|||
}, nil
|
||||
}
|
||||
|
||||
// NewInternalClient creates a new Public API client intended to run inside a
|
||||
// Kubernetes cluster.
|
||||
func NewInternalClient(controlPlaneNamespace string, kubeAPIHost string) (pb.ApiClient, error) {
|
||||
apiURL, err := url.Parse(fmt.Sprintf("http://%s/", kubeAPIHost))
|
||||
if err != nil {
|
||||
|
@ -199,6 +201,8 @@ func NewInternalClient(controlPlaneNamespace string, kubeAPIHost string) (pb.Api
|
|||
return newClient(apiURL, http.DefaultClient, controlPlaneNamespace)
|
||||
}
|
||||
|
||||
// NewExternalClient creates a new Public API client intended to run from
|
||||
// outside a Kubernetes cluster.
|
||||
func NewExternalClient(controlPlaneNamespace string, kubeAPI *k8s.KubernetesAPI) (pb.ApiClient, error) {
|
||||
apiURL, err := kubeAPI.URLFor(controlPlaneNamespace, "/services/linkerd-controller-api:http/proxy/")
|
||||
if err != nil {
|
||||
|
|
|
@ -39,10 +39,10 @@ type podReport struct {
|
|||
|
||||
const (
|
||||
podQuery = "max(process_start_time_seconds{%s}) by (pod, namespace)"
|
||||
K8sClientSubsystemName = "kubernetes"
|
||||
K8sClientCheckDescription = "control plane can talk to Kubernetes"
|
||||
PromClientSubsystemName = "prometheus"
|
||||
PromClientCheckDescription = "control plane can talk to Prometheus"
|
||||
k8sClientSubsystemName = "kubernetes"
|
||||
k8sClientCheckDescription = "control plane can talk to Kubernetes"
|
||||
promClientSubsystemName = "prometheus"
|
||||
promClientCheckDescription = "control plane can talk to Prometheus"
|
||||
)
|
||||
|
||||
func newGrpcServer(
|
||||
|
@ -190,8 +190,8 @@ func (s *grpcServer) ListPods(ctx context.Context, req *pb.ListPodsRequest) (*pb
|
|||
|
||||
func (s *grpcServer) SelfCheck(ctx context.Context, in *healthcheckPb.SelfCheckRequest) (*healthcheckPb.SelfCheckResponse, error) {
|
||||
k8sClientCheck := &healthcheckPb.CheckResult{
|
||||
SubsystemName: K8sClientSubsystemName,
|
||||
CheckDescription: K8sClientCheckDescription,
|
||||
SubsystemName: k8sClientSubsystemName,
|
||||
CheckDescription: k8sClientCheckDescription,
|
||||
Status: healthcheckPb.CheckStatus_OK,
|
||||
}
|
||||
_, err := s.k8sAPI.Pod().Lister().List(labels.Everything())
|
||||
|
@ -201,8 +201,8 @@ func (s *grpcServer) SelfCheck(ctx context.Context, in *healthcheckPb.SelfCheckR
|
|||
}
|
||||
|
||||
promClientCheck := &healthcheckPb.CheckResult{
|
||||
SubsystemName: PromClientSubsystemName,
|
||||
CheckDescription: PromClientCheckDescription,
|
||||
SubsystemName: promClientSubsystemName,
|
||||
CheckDescription: promClientCheckDescription,
|
||||
Status: healthcheckPb.CheckStatus_OK,
|
||||
}
|
||||
_, err = s.queryProm(ctx, fmt.Sprintf(podQuery, ""))
|
||||
|
|
|
@ -167,7 +167,7 @@ spec:
|
|||
}
|
||||
|
||||
fakeGrpcServer := newGrpcServer(
|
||||
&MockProm{Res: exp.promRes},
|
||||
&mockProm{Res: exp.promRes},
|
||||
tap.NewTapClient(nil),
|
||||
k8sAPI,
|
||||
"linkerd",
|
||||
|
@ -248,7 +248,7 @@ metadata:
|
|||
}
|
||||
|
||||
fakeGrpcServer := newGrpcServer(
|
||||
&MockProm{},
|
||||
&mockProm{},
|
||||
tap.NewTapClient(nil),
|
||||
k8sAPI,
|
||||
"linkerd",
|
||||
|
|
|
@ -239,6 +239,7 @@ func fullURLPathFor(method string) string {
|
|||
return apiRoot + apiPrefix + method
|
||||
}
|
||||
|
||||
// NewServer creates a Public API HTTP server.
|
||||
func NewServer(
|
||||
addr string,
|
||||
prometheusClient promApi.Client,
|
||||
|
|
|
@ -771,7 +771,7 @@ status:
|
|||
|
||||
for _, exp := range expectations {
|
||||
fakeGrpcServer := newGrpcServer(
|
||||
&MockProm{Res: exp.mockPromResponse},
|
||||
&mockProm{Res: exp.mockPromResponse},
|
||||
tap.NewTapClient(nil),
|
||||
k8sAPI,
|
||||
"linkerd",
|
||||
|
@ -795,7 +795,7 @@ status:
|
|||
t.Fatalf("NewFakeAPI returned an error: %s", err)
|
||||
}
|
||||
fakeGrpcServer := newGrpcServer(
|
||||
&MockProm{Res: model.Vector{}},
|
||||
&mockProm{Res: model.Vector{}},
|
||||
tap.NewTapClient(nil),
|
||||
k8sAPI,
|
||||
"linkerd",
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// MockAPIClient satisfies the Public API's gRPC interface.
|
||||
type MockAPIClient struct {
|
||||
ErrorToReturn error
|
||||
VersionInfoToReturn *pb.VersionInfo
|
||||
|
@ -30,45 +31,53 @@ type MockAPIClient struct {
|
|||
APITapByResourceClientToReturn pb.Api_TapByResourceClient
|
||||
}
|
||||
|
||||
// StatSummary provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) StatSummary(ctx context.Context, in *pb.StatSummaryRequest, opts ...grpc.CallOption) (*pb.StatSummaryResponse, error) {
|
||||
return c.StatSummaryResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
// TopRoutes provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) TopRoutes(ctx context.Context, in *pb.TopRoutesRequest, opts ...grpc.CallOption) (*pb.TopRoutesResponse, error) {
|
||||
return c.TopRoutesResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
// Version provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) Version(ctx context.Context, in *pb.Empty, opts ...grpc.CallOption) (*pb.VersionInfo, error) {
|
||||
return c.VersionInfoToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
// ListPods provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) ListPods(ctx context.Context, in *pb.ListPodsRequest, opts ...grpc.CallOption) (*pb.ListPodsResponse, error) {
|
||||
return c.ListPodsResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
// ListServices provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) ListServices(ctx context.Context, in *pb.ListServicesRequest, opts ...grpc.CallOption) (*pb.ListServicesResponse, error) {
|
||||
return c.ListServicesResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
// Tap provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) Tap(ctx context.Context, in *pb.TapRequest, opts ...grpc.CallOption) (pb.Api_TapClient, error) {
|
||||
return c.APITapClientToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
// TapByResource provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) TapByResource(ctx context.Context, in *pb.TapByResourceRequest, opts ...grpc.CallOption) (pb.Api_TapByResourceClient, error) {
|
||||
return c.APITapByResourceClientToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
// SelfCheck provides a mock of a Public API method.
|
||||
func (c *MockAPIClient) SelfCheck(ctx context.Context, in *healthcheckPb.SelfCheckRequest, _ ...grpc.CallOption) (*healthcheckPb.SelfCheckResponse, error) {
|
||||
return c.SelfCheckResponseToReturn, c.ErrorToReturn
|
||||
}
|
||||
|
||||
type MockAPITapClient struct {
|
||||
type mockAPITapClient struct {
|
||||
TapEventsToReturn []pb.TapEvent
|
||||
ErrorsToReturn []error
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (a *MockAPITapClient) Recv() (*pb.TapEvent, error) {
|
||||
func (a *mockAPITapClient) Recv() (*pb.TapEvent, error) {
|
||||
var eventPopped pb.TapEvent
|
||||
var errorPopped error
|
||||
if len(a.TapEventsToReturn) == 0 && len(a.ErrorsToReturn) == 0 {
|
||||
|
@ -84,12 +93,14 @@ func (a *MockAPITapClient) Recv() (*pb.TapEvent, error) {
|
|||
return &eventPopped, errorPopped
|
||||
}
|
||||
|
||||
// MockAPITapByResourceClient satisfies the TapByResourceClient gRPC interface.
|
||||
type MockAPITapByResourceClient struct {
|
||||
TapEventsToReturn []pb.TapEvent
|
||||
ErrorsToReturn []error
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
// Recv satisfies the TapByResourceClient.Recv() gRPC method.
|
||||
func (a *MockAPITapByResourceClient) Recv() (*pb.TapEvent, error) {
|
||||
var eventPopped pb.TapEvent
|
||||
var errorPopped error
|
||||
|
@ -110,37 +121,41 @@ func (a *MockAPITapByResourceClient) Recv() (*pb.TapEvent, error) {
|
|||
// Prometheus client
|
||||
//
|
||||
|
||||
type MockProm struct {
|
||||
type mockProm struct {
|
||||
Res model.Value
|
||||
QueriesExecuted []string // expose the queries our Mock Prometheus receives, to test query generation
|
||||
rwLock sync.Mutex
|
||||
}
|
||||
|
||||
// PodCounts is a test helper struct that is used for representing data in a
|
||||
// StatTable.PodGroup.Row.
|
||||
type PodCounts struct {
|
||||
MeshedPods uint64
|
||||
RunningPods uint64
|
||||
FailedPods uint64
|
||||
}
|
||||
|
||||
func (m *MockProm) Query(ctx context.Context, query string, ts time.Time) (model.Value, error) {
|
||||
func (m *mockProm) Query(ctx context.Context, query string, ts time.Time) (model.Value, error) {
|
||||
m.rwLock.Lock()
|
||||
defer m.rwLock.Unlock()
|
||||
m.QueriesExecuted = append(m.QueriesExecuted, query)
|
||||
return m.Res, nil
|
||||
}
|
||||
func (m *MockProm) QueryRange(ctx context.Context, query string, r v1.Range) (model.Value, error) {
|
||||
func (m *mockProm) QueryRange(ctx context.Context, query string, r v1.Range) (model.Value, error) {
|
||||
m.rwLock.Lock()
|
||||
defer m.rwLock.Unlock()
|
||||
m.QueriesExecuted = append(m.QueriesExecuted, query)
|
||||
return m.Res, nil
|
||||
}
|
||||
func (m *MockProm) LabelValues(ctx context.Context, label string) (model.LabelValues, error) {
|
||||
func (m *mockProm) LabelValues(ctx context.Context, label string) (model.LabelValues, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *MockProm) Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, error) {
|
||||
func (m *mockProm) Series(ctx context.Context, matches []string, startTime time.Time, endTime time.Time) ([]model.LabelSet, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GenStatSummaryResponse generates a mock Public API StatSummaryResponse
|
||||
// object.
|
||||
func GenStatSummaryResponse(resName, resType string, resNs []string, counts *PodCounts, basicStats bool) pb.StatSummaryResponse {
|
||||
rows := []*pb.StatTable_PodGroup_Row{}
|
||||
for _, ns := range resNs {
|
||||
|
@ -192,6 +207,7 @@ func GenStatSummaryResponse(resName, resType string, resNs []string, counts *Pod
|
|||
return resp
|
||||
}
|
||||
|
||||
// GenTopRoutesResponse generates a mock Public API TopRoutesResponse object.
|
||||
func GenTopRoutesResponse(routes []string, counts []uint64) pb.TopRoutesResponse {
|
||||
rows := []*pb.RouteTable_Row{}
|
||||
for i, route := range routes {
|
||||
|
@ -228,13 +244,13 @@ type expectedStatRPC struct {
|
|||
expectedPrometheusQueries []string // queries we expect public-api to issue to prometheus
|
||||
}
|
||||
|
||||
func newMockGrpcServer(exp expectedStatRPC) (*MockProm, *grpcServer, error) {
|
||||
func newMockGrpcServer(exp expectedStatRPC) (*mockProm, *grpcServer, error) {
|
||||
k8sAPI, err := k8s.NewFakeAPI("", exp.k8sConfigs...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
mockProm := &MockProm{Res: exp.mockPromResponse}
|
||||
mockProm := &mockProm{Res: exp.mockPromResponse}
|
||||
fakeGrpcServer := newGrpcServer(
|
||||
mockProm,
|
||||
tap.NewTapClient(nil),
|
||||
|
@ -248,7 +264,7 @@ func newMockGrpcServer(exp expectedStatRPC) (*MockProm, *grpcServer, error) {
|
|||
return mockProm, fakeGrpcServer, nil
|
||||
}
|
||||
|
||||
func (exp expectedStatRPC) verifyPromQueries(mockProm *MockProm) error {
|
||||
func (exp expectedStatRPC) verifyPromQueries(mockProm *mockProm) error {
|
||||
// if exp.expectedPrometheusQueries is an empty slice we still wanna check no queries were executed.
|
||||
if exp.expectedPrometheusQueries != nil {
|
||||
sort.Strings(exp.expectedPrometheusQueries)
|
||||
|
|
|
@ -49,7 +49,7 @@ var (
|
|||
)
|
||||
|
||||
// StatsBaseRequestParams contains parameters that are used to build requests
|
||||
// for metrics data. This includes requests to StatSummary and TopRoutes
|
||||
// for metrics data. This includes requests to StatSummary and TopRoutes.
|
||||
type StatsBaseRequestParams struct {
|
||||
TimeWindow string
|
||||
Namespace string
|
||||
|
@ -58,6 +58,8 @@ type StatsBaseRequestParams struct {
|
|||
AllNamespaces bool
|
||||
}
|
||||
|
||||
// StatsSummaryRequestParams contains parameters that are used to build
|
||||
// StatSummary requests.
|
||||
type StatsSummaryRequestParams struct {
|
||||
StatsBaseRequestParams
|
||||
ToNamespace string
|
||||
|
@ -69,12 +71,16 @@ type StatsSummaryRequestParams struct {
|
|||
SkipStats bool
|
||||
}
|
||||
|
||||
// TopRoutesRequestParams contains parameters that are used to build TopRoutes
|
||||
// requests.
|
||||
type TopRoutesRequestParams struct {
|
||||
StatsBaseRequestParams
|
||||
To string
|
||||
ToAll bool
|
||||
}
|
||||
|
||||
// TapRequestParams contains parameters that are used to build a
|
||||
// TapByResourceRequest.
|
||||
type TapRequestParams struct {
|
||||
Resource string
|
||||
Namespace string
|
||||
|
@ -119,6 +125,8 @@ func GRPCError(err error) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// BuildStatSummaryRequest builds a Public API StatSummaryRequest from a
|
||||
// StatsSummaryRequestParams.
|
||||
func BuildStatSummaryRequest(p StatsSummaryRequestParams) (*pb.StatSummaryRequest, error) {
|
||||
window := defaultMetricTimeWindow
|
||||
if p.TimeWindow != "" {
|
||||
|
@ -206,6 +214,8 @@ func BuildStatSummaryRequest(p StatsSummaryRequestParams) (*pb.StatSummaryReques
|
|||
return statRequest, nil
|
||||
}
|
||||
|
||||
// BuildTopRoutesRequest builds a Public API TopRoutesRequest from a
|
||||
// TopRoutesRequestParams.
|
||||
func BuildTopRoutesRequest(p TopRoutesRequestParams) (*pb.TopRoutesRequest, error) {
|
||||
window := defaultMetricTimeWindow
|
||||
if p.TimeWindow != "" {
|
||||
|
@ -372,6 +382,8 @@ func buildResource(namespace string, resType string, name string) (pb.Resource,
|
|||
}, nil
|
||||
}
|
||||
|
||||
// BuildTapByResourceRequest builds a Public API TapByResourceRequest from a
|
||||
// TapRequestParams.
|
||||
func BuildTapByResourceRequest(params TapRequestParams) (*pb.TapByResourceRequest, error) {
|
||||
target, err := BuildResource(params.Namespace, params.Resource)
|
||||
if err != nil {
|
||||
|
@ -535,6 +547,8 @@ func routeLabels(event *pb.TapEvent) string {
|
|||
return out
|
||||
}
|
||||
|
||||
// RenderTapEvent renders a Public API TapEvent to a string.
|
||||
// TODO: consider moving this into cli/cmd/tap.go.
|
||||
func RenderTapEvent(event *pb.TapEvent, resource string) string {
|
||||
dst := dst(event)
|
||||
src := src(event)
|
||||
|
@ -634,6 +648,8 @@ func RenderTapEvent(event *pb.TapEvent, resource string) string {
|
|||
}
|
||||
}
|
||||
|
||||
// GetRequestRate calculates request rate from Public API BasicStats.
|
||||
// TODO: consider moving this into `/cli/cmd`.
|
||||
func GetRequestRate(stats *pb.BasicStats, timeWindow string) float64 {
|
||||
success := stats.SuccessCount
|
||||
failure := stats.FailureCount
|
||||
|
@ -645,6 +661,8 @@ func GetRequestRate(stats *pb.BasicStats, timeWindow string) float64 {
|
|||
return float64(success+failure) / windowLength.Seconds()
|
||||
}
|
||||
|
||||
// GetSuccessRate calculates success rate from Public API BasicStats.
|
||||
// TODO: consider moving this into `/cli/cmd`.
|
||||
func GetSuccessRate(stats *pb.BasicStats) float64 {
|
||||
success := stats.SuccessCount
|
||||
failure := stats.FailureCount
|
||||
|
@ -655,6 +673,9 @@ func GetSuccessRate(stats *pb.BasicStats) float64 {
|
|||
return float64(success) / float64(success+failure)
|
||||
}
|
||||
|
||||
// GetPercentTLS calculates the percent of traffic that is TLS, from Public API
|
||||
// BasicStats.
|
||||
// TODO: consider moving this into `/cli/cmd/stat.go`.
|
||||
func GetPercentTLS(stats *pb.BasicStats) float64 {
|
||||
reqTotal := stats.SuccessCount + stats.FailureCount
|
||||
if reqTotal == 0 {
|
||||
|
|
|
@ -48,6 +48,7 @@ type CA struct {
|
|||
nextSerialNumber uint64
|
||||
}
|
||||
|
||||
// CertificateAndPrivateKey encapsulates a certificate / private key pair.
|
||||
type CertificateAndPrivateKey struct {
|
||||
// The ASN.1 DER-encoded (binary, not PEM) certificate.
|
||||
Certificate []byte
|
||||
|
|
|
@ -18,6 +18,8 @@ import (
|
|||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
// CertificateController listens for added and updated meshed pods, and then
|
||||
// provides certificates in the form of secrets.
|
||||
type CertificateController struct {
|
||||
namespace string
|
||||
k8sAPI *k8s.API
|
||||
|
@ -32,6 +34,8 @@ type CertificateController struct {
|
|||
queue workqueue.RateLimitingInterface
|
||||
}
|
||||
|
||||
// NewCertificateController initializes a CertificateController and its
|
||||
// internal Certificate Authority.
|
||||
func NewCertificateController(controllerNamespace string, k8sAPI *k8s.API, proxyAutoInject bool) (*CertificateController, error) {
|
||||
ca, err := NewCA()
|
||||
if err != nil {
|
||||
|
@ -67,6 +71,7 @@ func NewCertificateController(controllerNamespace string, k8sAPI *k8s.API, proxy
|
|||
return c, nil
|
||||
}
|
||||
|
||||
// Run kicks off CertificateController queue processing.
|
||||
func (c *CertificateController) Run(stopCh <-chan struct{}) {
|
||||
defer runtime.HandleCrash()
|
||||
defer c.queue.ShutDown()
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
package serviceprofile
|
||||
|
||||
// GroupName identifies the API Group Name for a ServiceProfile.
|
||||
const GroupName = "linkerd.io"
|
||||
|
|
|
@ -26,8 +26,15 @@ func Resource(resource string) schema.GroupResource {
|
|||
}
|
||||
|
||||
var (
|
||||
// SchemeBuilder collects functions that add things to a scheme. It's to allow
|
||||
// code to compile without explicitly referencing generated types. You should
|
||||
// declare one in each package that will have generated deep copy or conversion
|
||||
// functions.
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
|
||||
// AddToScheme applies all the stored functions to the scheme. A non-nil error
|
||||
// indicates that one function failed and the attempt was abandoned.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
|
|
|
@ -25,16 +25,19 @@ type ServiceProfile struct {
|
|||
Spec ServiceProfileSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// ServiceProfileSpec specifies a ServiceProfile resource.
|
||||
type ServiceProfileSpec struct {
|
||||
Routes []*RouteSpec `json:"routes"`
|
||||
}
|
||||
|
||||
// RouteSpec specifies a Route resource.
|
||||
type RouteSpec struct {
|
||||
Name string `json:"name"`
|
||||
Condition *RequestMatch `json:"condition"`
|
||||
ResponseClasses []*ResponseClass `json:"responseClasses,omitempty"`
|
||||
}
|
||||
|
||||
// RequestMatch describes the conditions under which to match a Route.
|
||||
type RequestMatch struct {
|
||||
All []*RequestMatch `json:"all,omitempty"`
|
||||
Not *RequestMatch `json:"not,omitempty"`
|
||||
|
@ -43,11 +46,14 @@ type RequestMatch struct {
|
|||
Method string `json:"method,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseClass describes how to classify a response (e.g. success or
|
||||
// failures).
|
||||
type ResponseClass struct {
|
||||
Condition *ResponseMatch `json:"condition"`
|
||||
IsFailure bool `json:"isFailure,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseMatch describes the conditions under which to classify a response.
|
||||
type ResponseMatch struct {
|
||||
All []*ResponseMatch `json:"all,omitempty"`
|
||||
Not *ResponseMatch `json:"not,omitempty"`
|
||||
|
@ -55,6 +61,7 @@ type ResponseMatch struct {
|
|||
Status *Range `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Range describes a range of integers (e.g. status codes).
|
||||
type Range struct {
|
||||
Min uint32 `json:"min,omitempty"`
|
||||
Max uint32 `json:"max,omitempty"`
|
||||
|
@ -62,7 +69,7 @@ type Range struct {
|
|||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ServiceProfileList is a list of ServiceProfile resources
|
||||
// ServiceProfileList is a list of ServiceProfile resources.
|
||||
type ServiceProfileList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
|
|
|
@ -26,8 +26,11 @@ import (
|
|||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// APIResource is an enum for Kubernetes API resource types, for use when
|
||||
// initializing a K8s API, to describe which resource types to interact with.
|
||||
type APIResource int
|
||||
|
||||
// These constants enumerate Kubernetes resource types.
|
||||
const (
|
||||
CM APIResource = iota
|
||||
Deploy
|
||||
|
@ -140,6 +143,7 @@ func (api *API) Sync() {
|
|||
log.Infof("caches synced")
|
||||
}
|
||||
|
||||
// Deploy provides access to a shared informer and lister for Deployments.
|
||||
func (api *API) Deploy() appinformers.DeploymentInformer {
|
||||
if api.deploy == nil {
|
||||
panic("Deploy informer not configured")
|
||||
|
@ -147,6 +151,7 @@ func (api *API) Deploy() appinformers.DeploymentInformer {
|
|||
return api.deploy
|
||||
}
|
||||
|
||||
// RS provides access to a shared informer and lister for ReplicaSets.
|
||||
func (api *API) RS() appinformers.ReplicaSetInformer {
|
||||
if api.rs == nil {
|
||||
panic("RS informer not configured")
|
||||
|
@ -154,6 +159,7 @@ func (api *API) RS() appinformers.ReplicaSetInformer {
|
|||
return api.rs
|
||||
}
|
||||
|
||||
// Pod provides access to a shared informer and lister for Pods.
|
||||
func (api *API) Pod() coreinformers.PodInformer {
|
||||
if api.pod == nil {
|
||||
panic("Pod informer not configured")
|
||||
|
@ -161,6 +167,8 @@ func (api *API) Pod() coreinformers.PodInformer {
|
|||
return api.pod
|
||||
}
|
||||
|
||||
// RC provides access to a shared informer and lister for
|
||||
// ReplicationControllers.
|
||||
func (api *API) RC() coreinformers.ReplicationControllerInformer {
|
||||
if api.rc == nil {
|
||||
panic("RC informer not configured")
|
||||
|
@ -168,6 +176,7 @@ func (api *API) RC() coreinformers.ReplicationControllerInformer {
|
|||
return api.rc
|
||||
}
|
||||
|
||||
// Svc provides access to a shared informer and lister for Services.
|
||||
func (api *API) Svc() coreinformers.ServiceInformer {
|
||||
if api.svc == nil {
|
||||
panic("Svc informer not configured")
|
||||
|
@ -175,6 +184,7 @@ func (api *API) Svc() coreinformers.ServiceInformer {
|
|||
return api.svc
|
||||
}
|
||||
|
||||
// Endpoint provides access to a shared informer and lister for Endpoints.
|
||||
func (api *API) Endpoint() coreinformers.EndpointsInformer {
|
||||
if api.endpoint == nil {
|
||||
panic("Endpoint informer not configured")
|
||||
|
@ -182,6 +192,7 @@ func (api *API) Endpoint() coreinformers.EndpointsInformer {
|
|||
return api.endpoint
|
||||
}
|
||||
|
||||
// CM provides access to a shared informer and lister for ConfigMaps.
|
||||
func (api *API) CM() coreinformers.ConfigMapInformer {
|
||||
if api.cm == nil {
|
||||
panic("CM informer not configured")
|
||||
|
@ -189,6 +200,7 @@ func (api *API) CM() coreinformers.ConfigMapInformer {
|
|||
return api.cm
|
||||
}
|
||||
|
||||
// SP provides access to a shared informer and lister for ServiceProfiles.
|
||||
func (api *API) SP() spinformers.ServiceProfileInformer {
|
||||
if api.sp == nil {
|
||||
panic("SP informer not configured")
|
||||
|
@ -196,6 +208,7 @@ func (api *API) SP() spinformers.ServiceProfileInformer {
|
|||
return api.sp
|
||||
}
|
||||
|
||||
// MWC provides access to a shared informer and lister for MutatingWebhookConfigurations.
|
||||
func (api *API) MWC() arinformers.MutatingWebhookConfigurationInformer {
|
||||
if api.mwc == nil {
|
||||
panic("MWC informer not configured")
|
||||
|
@ -439,6 +452,8 @@ func (api *API) getServices(namespace, name string) ([]runtime.Object, error) {
|
|||
return objects, nil
|
||||
}
|
||||
|
||||
// GetServices returns a list of Service resources, based on input namespace and
|
||||
// name.
|
||||
func (api *API) GetServices(namespace, name string) ([]*apiv1.Service, error) {
|
||||
var err error
|
||||
var services []*apiv1.Service
|
||||
|
|
|
@ -4,10 +4,12 @@ import (
|
|||
spclient "github.com/linkerd/linkerd2/controller/gen/client/clientset/versioned"
|
||||
"github.com/linkerd/linkerd2/pkg/k8s"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
// Load all the auth plugins for the cloud providers.
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
)
|
||||
|
||||
// NewClientSet returns a Kubernetes client for the given configuration.
|
||||
func NewClientSet(kubeConfig string) (*kubernetes.Clientset, error) {
|
||||
config, err := k8s.GetConfig(kubeConfig, "")
|
||||
if err != nil {
|
||||
|
@ -17,6 +19,8 @@ func NewClientSet(kubeConfig string) (*kubernetes.Clientset, error) {
|
|||
return kubernetes.NewForConfig(config)
|
||||
}
|
||||
|
||||
// NewSpClientSet returns a Kubernetes ServiceProfile client for the given
|
||||
// configuration.
|
||||
func NewSpClientSet(kubeConfig string) (*spclient.Clientset, error) {
|
||||
config, err := k8s.GetConfig(kubeConfig, "")
|
||||
if err != nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ func toRuntimeObject(config string) (runtime.Object, error) {
|
|||
return obj, err
|
||||
}
|
||||
|
||||
// NewFakeAPI provides a mock Kubernetes API for testing.
|
||||
func NewFakeAPI(namespace string, configs ...string) (*API, error) {
|
||||
objs := []runtime.Object{}
|
||||
spObjs := []runtime.Object{}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// These constants provide default, fake strings for testing proxy-injector.
|
||||
const (
|
||||
DefaultControllerNamespace = "linkerd"
|
||||
DefaultNamespace = "default"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package tmpl
|
||||
|
||||
// MutatingWebhookConfigurationSpec provides a template for a
|
||||
// MutatingWebhookConfiguration.
|
||||
var MutatingWebhookConfigurationSpec = `
|
||||
apiVersion: admissionregistration.k8s.io/v1beta1
|
||||
kind: MutatingWebhookConfiguration
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// NewClient creates a client for the control-plane's Tap service.
|
||||
func NewClient(addr string) (pb.TapClient, *grpc.ClientConn, error) {
|
||||
conn, err := grpc.Dial(addr, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
|
|
|
@ -9,21 +9,25 @@ import (
|
|||
"github.com/linkerd/linkerd2/controller/gen/public"
|
||||
)
|
||||
|
||||
// PublicAddressToString formats a Public API TCPAddress as a string.
|
||||
func PublicAddressToString(addr *public.TcpAddress) string {
|
||||
octects := decodeIPToOctets(addr.GetIp().GetIpv4())
|
||||
return fmt.Sprintf("%d.%d.%d.%d:%d", octects[0], octects[1], octects[2], octects[3], addr.GetPort())
|
||||
}
|
||||
|
||||
// PublicIPToString formats a Public API IPAddress as a string.
|
||||
func PublicIPToString(ip *public.IPAddress) string {
|
||||
octets := decodeIPToOctets(ip.GetIpv4())
|
||||
return fmt.Sprintf("%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3])
|
||||
}
|
||||
|
||||
// ProxyAddressToString formats a Proxy API TCPAddress as a string.
|
||||
func ProxyAddressToString(addr *pb.TcpAddress) string {
|
||||
octects := decodeIPToOctets(addr.GetIp().GetIpv4())
|
||||
return fmt.Sprintf("%d.%d.%d.%d:%d", octects[0], octects[1], octects[2], octects[3], addr.GetPort())
|
||||
}
|
||||
|
||||
// ProxyAddressesToString formats a list of Proxy API TCPAddresses as a string.
|
||||
func ProxyAddressesToString(addrs []pb.TcpAddress) string {
|
||||
addrStrs := make([]string, len(addrs))
|
||||
for i := range addrs {
|
||||
|
@ -32,11 +36,13 @@ func ProxyAddressesToString(addrs []pb.TcpAddress) string {
|
|||
return "[" + strings.Join(addrStrs, ",") + "]"
|
||||
}
|
||||
|
||||
// ProxyIPToString formats a Proxy API IPAddress as a string.
|
||||
func ProxyIPToString(ip *pb.IPAddress) string {
|
||||
octets := decodeIPToOctets(ip.GetIpv4())
|
||||
return fmt.Sprintf("%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3])
|
||||
}
|
||||
|
||||
// ProxyIPV4 encodes 4 octets as a Proxy API IPAddress.
|
||||
func ProxyIPV4(a1, a2, a3, a4 uint8) *pb.IPAddress {
|
||||
ip := (uint32(a1) << 24) | (uint32(a2) << 16) | (uint32(a3) << 8) | uint32(a4)
|
||||
return &pb.IPAddress{
|
||||
|
@ -46,6 +52,7 @@ func ProxyIPV4(a1, a2, a3, a4 uint8) *pb.IPAddress {
|
|||
}
|
||||
}
|
||||
|
||||
// ParseProxyIPV4 parses an IP Address string into a Proxy API IPAddress.
|
||||
func ParseProxyIPV4(ip string) (*pb.IPAddress, error) {
|
||||
segments := strings.Split(ip, ".")
|
||||
if len(segments) != 4 {
|
||||
|
@ -62,6 +69,7 @@ func ParseProxyIPV4(ip string) (*pb.IPAddress, error) {
|
|||
return ProxyIPV4(octets[0], octets[1], octets[2], octets[3]), nil
|
||||
}
|
||||
|
||||
// PublicIPV4 encodes 4 octets as a Public API IPAddress.
|
||||
func PublicIPV4(a1, a2, a3, a4 uint8) *public.IPAddress {
|
||||
ip := (uint32(a1) << 24) | (uint32(a2) << 16) | (uint32(a3) << 8) | uint32(a4)
|
||||
return &public.IPAddress{
|
||||
|
@ -71,6 +79,7 @@ func PublicIPV4(a1, a2, a3, a4 uint8) *public.IPAddress {
|
|||
}
|
||||
}
|
||||
|
||||
// ParsePublicIPV4 parses an IP Address string into a Public API IPAddress.
|
||||
func ParsePublicIPV4(ip string) (*public.IPAddress, error) {
|
||||
segments := strings.Split(ip, ".")
|
||||
if len(segments) != 4 {
|
||||
|
|
|
@ -12,6 +12,7 @@ type handler struct {
|
|||
promHandler http.Handler
|
||||
}
|
||||
|
||||
// StartServer starts an admin server listening on a given address.
|
||||
func StartServer(addr string) {
|
||||
log.Infof("starting admin server on %s", addr)
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
// FileSystem provides access to a collection of named files via
|
||||
// http.FileSystem, given a directory.
|
||||
func FileSystem(dir string) http.FileSystem {
|
||||
return fileSystem{http.Dir(dir)}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
// Checks is an enum for the types of health checks.
|
||||
type Checks int
|
||||
|
||||
const (
|
||||
|
@ -56,11 +57,19 @@ const (
|
|||
// and ShouldCheckDataPlaneVersion options are false.
|
||||
LinkerdVersionChecks
|
||||
|
||||
KubernetesAPICategory = "kubernetes-api"
|
||||
// KubernetesAPICategory is the string representation of KubernetesAPIChecks.
|
||||
KubernetesAPICategory = "kubernetes-api"
|
||||
// LinkerdPreInstallCategory is the string representation of
|
||||
// LinkerdPreInstallChecks.
|
||||
LinkerdPreInstallCategory = "kubernetes-setup"
|
||||
LinkerdDataPlaneCategory = "linkerd-data-plane"
|
||||
LinkerdAPICategory = "linkerd-api"
|
||||
LinkerdVersionCategory = "linkerd-version"
|
||||
// LinkerdDataPlaneCategory is the string representation of
|
||||
// LinkerdDataPlaneChecks.
|
||||
LinkerdDataPlaneCategory = "linkerd-data-plane"
|
||||
// LinkerdAPICategory is the string representation of LinkerdAPIChecks.
|
||||
LinkerdAPICategory = "linkerd-api"
|
||||
// LinkerdVersionCategory is the string representation of
|
||||
// LinkerdVersionChecks.
|
||||
LinkerdVersionCategory = "linkerd-version"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -100,6 +109,7 @@ type checker struct {
|
|||
checkRPC func() (*healthcheckPb.SelfCheckResponse, error)
|
||||
}
|
||||
|
||||
// CheckResult encapsulates a check's identifying information and output
|
||||
type CheckResult struct {
|
||||
Category string
|
||||
Description string
|
||||
|
@ -110,6 +120,7 @@ type CheckResult struct {
|
|||
|
||||
type checkObserver func(*CheckResult)
|
||||
|
||||
// Options specifies configuration for a HealthChecker.
|
||||
type Options struct {
|
||||
ControlPlaneNamespace string
|
||||
DataPlaneNamespace string
|
||||
|
@ -124,6 +135,8 @@ type Options struct {
|
|||
SingleNamespace bool
|
||||
}
|
||||
|
||||
// HealthChecker encapsulates all health check checkers, and clients required to
|
||||
// perform those checks.
|
||||
type HealthChecker struct {
|
||||
checkers []*checker
|
||||
*Options
|
||||
|
@ -139,6 +152,7 @@ type HealthChecker struct {
|
|||
latestVersion string
|
||||
}
|
||||
|
||||
// NewHealthChecker returns an initialized HealthChecker
|
||||
func NewHealthChecker(checks []Checks, options *Options) *HealthChecker {
|
||||
hc := &HealthChecker{
|
||||
checkers: make([]*checker, 0),
|
||||
|
|
|
@ -19,10 +19,13 @@ import (
|
|||
|
||||
var minAPIVersion = [3]int{1, 8, 0}
|
||||
|
||||
// KubernetesAPI provides a client for accessing a Kubernetes cluster.
|
||||
type KubernetesAPI struct {
|
||||
*rest.Config
|
||||
}
|
||||
|
||||
// NewClient returns an http.Client configured with a Transport to connect to
|
||||
// the Kubernetes cluster.
|
||||
func (kubeAPI *KubernetesAPI) NewClient() (*http.Client, error) {
|
||||
secureTransport, err := rest.TransportFor(kubeAPI.Config)
|
||||
if err != nil {
|
||||
|
@ -34,6 +37,7 @@ func (kubeAPI *KubernetesAPI) NewClient() (*http.Client, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// GetVersionInfo returns version.Info for the Kubernetes cluster.
|
||||
func (kubeAPI *KubernetesAPI) GetVersionInfo(client *http.Client) (*version.Info, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
@ -58,6 +62,8 @@ func (kubeAPI *KubernetesAPI) GetVersionInfo(client *http.Client) (*version.Info
|
|||
return &versionInfo, err
|
||||
}
|
||||
|
||||
// CheckVersion validates whether the configured Kubernetes cluster's version is
|
||||
// running a minimum Kubernetes API version.
|
||||
func (kubeAPI *KubernetesAPI) CheckVersion(versionInfo *version.Info) error {
|
||||
apiVersion, err := getK8sVersion(versionInfo.String())
|
||||
if err != nil {
|
||||
|
@ -73,6 +79,7 @@ func (kubeAPI *KubernetesAPI) CheckVersion(versionInfo *version.Info) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// NamespaceExists validates whether a given namespace exists.
|
||||
func (kubeAPI *KubernetesAPI) NamespaceExists(client *http.Client, namespace string) (bool, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
// These constants are string representations of Kubernetes resource types.
|
||||
const (
|
||||
All = "all"
|
||||
Authority = "authority"
|
||||
|
@ -159,6 +160,10 @@ func ShortNameFromCanonicalResourceName(canonicalName string) string {
|
|||
}
|
||||
}
|
||||
|
||||
// KindToL5DLabel converts a Kubernetes `kind` to a Linkerd label.
|
||||
// For example:
|
||||
// `pod` -> `pod`
|
||||
// `job` -> `k8s_job`
|
||||
func KindToL5DLabel(k8sKind string) string {
|
||||
if k8sKind == Job {
|
||||
return l5dJob
|
||||
|
|
|
@ -120,7 +120,12 @@ const (
|
|||
// that contains the actual trust anchor bundle.
|
||||
TLSTrustAnchorFileName = "trust-anchors.pem"
|
||||
|
||||
TLSCertFileName = "certificate.crt"
|
||||
// TLSCertFileName is the name (key) within proxy-injector ConfigMap that
|
||||
// contains the TLS certificate.
|
||||
TLSCertFileName = "certificate.crt"
|
||||
|
||||
// TLSPrivateKeyFileName is the name (key) within proxy-injector ConfigMap
|
||||
// that contains the TLS private key.
|
||||
TLSPrivateKeyFileName = "private-key.p8"
|
||||
|
||||
/*
|
||||
|
@ -185,6 +190,7 @@ func GetPodLabels(ownerKind, ownerName string, pod *coreV1.Pod) map[string]strin
|
|||
return labels
|
||||
}
|
||||
|
||||
// IsMeshed returns whether a given Pod is in a given controller's service mesh.
|
||||
func IsMeshed(pod *coreV1.Pod, controllerNS string) bool {
|
||||
return pod.Labels[ControllerNSLabel] == controllerNS
|
||||
}
|
||||
|
@ -207,6 +213,7 @@ type TLSIdentity struct {
|
|||
ControllerNamespace string
|
||||
}
|
||||
|
||||
// ToDNSName formats a TLSIdentity as a DNS name.
|
||||
func (i TLSIdentity) ToDNSName() string {
|
||||
if i.Kind == Service {
|
||||
return fmt.Sprintf("%s.%s.svc", i.Name, i.Namespace)
|
||||
|
@ -215,10 +222,13 @@ func (i TLSIdentity) ToDNSName() string {
|
|||
i.Kind, i.Namespace, i.ControllerNamespace)
|
||||
}
|
||||
|
||||
// ToSecretName formats a TLSIdentity as a secret name.
|
||||
func (i TLSIdentity) ToSecretName() string {
|
||||
return fmt.Sprintf("%s-%s-tls-linkerd-io", i.Name, i.Kind)
|
||||
}
|
||||
|
||||
// ToControllerIdentity returns the TLSIdentity of the Linkerd Controller, given
|
||||
// an arbitrary TLSIdentity.
|
||||
func (i TLSIdentity) ToControllerIdentity() TLSIdentity {
|
||||
return TLSIdentity{
|
||||
Name: "controller",
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
)
|
||||
|
||||
// KubernetesProxy provides a proxied connection into a Kubernetes cluster.
|
||||
type KubernetesProxy struct {
|
||||
listener net.Listener
|
||||
server *proxy.Server
|
||||
|
|
|
@ -18,6 +18,7 @@ type profileTemplateConfig struct {
|
|||
ClusterZone string
|
||||
}
|
||||
|
||||
// ToRoute returns a Proxy API Route, given a ServiceProfile Route.
|
||||
func ToRoute(route *sp.RouteSpec) (*pb.Route, error) {
|
||||
cond, err := ToRequestMatch(route.Condition)
|
||||
if err != nil {
|
||||
|
@ -38,6 +39,8 @@ func ToRoute(route *sp.RouteSpec) (*pb.Route, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ToResponseClass returns a Proxy API ResponseClass, given a ServiceProfile
|
||||
// ResponseClass.
|
||||
func ToResponseClass(rc *sp.ResponseClass) (*pb.ResponseClass, error) {
|
||||
cond, err := ToResponseMatch(rc.Condition)
|
||||
if err != nil {
|
||||
|
@ -49,6 +52,8 @@ func ToResponseClass(rc *sp.ResponseClass) (*pb.ResponseClass, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ToResponseMatch returns a Proxy API ResponseMatch, given a ServiceProfile
|
||||
// ResponseMatch.
|
||||
func ToResponseMatch(rspMatch *sp.ResponseMatch) (*pb.ResponseMatch, error) {
|
||||
if rspMatch == nil {
|
||||
return nil, errors.New("missing response match")
|
||||
|
@ -134,6 +139,8 @@ func ToResponseMatch(rspMatch *sp.ResponseMatch) (*pb.ResponseMatch, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ToRequestMatch returns a Proxy API RequestMatch, given a ServiceProfile
|
||||
// RequestMatch.
|
||||
func ToRequestMatch(reqMatch *sp.RequestMatch) (*pb.RequestMatch, error) {
|
||||
if reqMatch == nil {
|
||||
return nil, errors.New("missing request match")
|
||||
|
@ -226,6 +233,8 @@ func ToRequestMatch(reqMatch *sp.RequestMatch) (*pb.RequestMatch, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ValidateRequestMatch validates whether a ServiceProfile RequestMatch has at
|
||||
// least one field set.
|
||||
func ValidateRequestMatch(reqMatch *sp.RequestMatch) error {
|
||||
matchKindSet := false
|
||||
if reqMatch.All != nil {
|
||||
|
@ -267,6 +276,8 @@ func ValidateRequestMatch(reqMatch *sp.RequestMatch) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ValidateResponseMatch validates whether a ServiceProfile ResponseMatch has at
|
||||
// least one field set, and sanity checks the Status Range.
|
||||
func ValidateResponseMatch(rspMatch *sp.ResponseMatch) error {
|
||||
invalidRangeErr := errors.New("Range maximum cannot be smaller than minimum")
|
||||
matchKindSet := false
|
||||
|
@ -318,6 +329,8 @@ func buildConfig(namespace, service, controlPlaneNamespace string) *profileTempl
|
|||
}
|
||||
}
|
||||
|
||||
// RenderProfileTemplate renders a ServiceProfile template to a buffer, given a
|
||||
// namespace, service, and control plane namespace.
|
||||
func RenderProfileTemplate(namespace, service, controlPlaneNamespace string, w io.Writer) error {
|
||||
config := buildConfig(namespace, service, controlPlaneNamespace)
|
||||
template, err := template.New("profile").Parse(Template)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// GenServiceProfile generates a mock ServiceProfile.
|
||||
func GenServiceProfile(service, namespace, controlPlaneNamespace string) v1alpha1.ServiceProfile {
|
||||
return v1alpha1.ServiceProfile{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
|
@ -44,6 +45,7 @@ func GenServiceProfile(service, namespace, controlPlaneNamespace string) v1alpha
|
|||
}
|
||||
}
|
||||
|
||||
// ServiceProfileYamlEquals validates whether two ServiceProfiles are equal.
|
||||
func ServiceProfileYamlEquals(actual, expected v1alpha1.ServiceProfile) error {
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
acutalYaml, err := yaml.Marshal(actual)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// Supported TLS key types.
|
||||
const (
|
||||
KeyTypeRSA = "rsa"
|
||||
KeyTypeECDSA = "ecdsa"
|
||||
|
|
|
@ -37,6 +37,8 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
// CheckClientVersion validates whether the Linkerd Public API client's version
|
||||
// matches an expected version.
|
||||
func CheckClientVersion(expectedVersion string) error {
|
||||
if Version != expectedVersion {
|
||||
return versionMismatchError(expectedVersion, Version)
|
||||
|
@ -45,6 +47,8 @@ func CheckClientVersion(expectedVersion string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// CheckServerVersion validates whether the Linkerd Public API server's version
|
||||
// matches an expected version.
|
||||
func CheckServerVersion(apiClient pb.ApiClient, expectedVersion string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
@ -61,6 +65,8 @@ func CheckServerVersion(apiClient pb.ApiClient, expectedVersion string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetLatestVersion performs an online request to check for the latest Linkerd
|
||||
// version.
|
||||
func GetLatestVersion(uuid string, source string) (string, error) {
|
||||
url := fmt.Sprintf(versionCheckURL, Version, uuid, source)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
|
|
|
@ -29,6 +29,8 @@ func newRootOptions() *rootOptions {
|
|||
}
|
||||
}
|
||||
|
||||
// NewRootCmd returns a configured cobra.Command for the `proxy-init` command.
|
||||
// TODO: consider moving this to `/proxy-init/main.go`
|
||||
func NewRootCmd() *cobra.Command {
|
||||
options := newRootOptions()
|
||||
|
||||
|
|
|
@ -10,16 +10,26 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
RedirectAllMode = "redirect-all"
|
||||
RedirectListedMode = "redirect-listed"
|
||||
// RedirectAllMode indicates redirecting all ports.
|
||||
RedirectAllMode = "redirect-all"
|
||||
|
||||
// RedirectListedMode indicates redirecting a given list of ports.
|
||||
RedirectListedMode = "redirect-listed"
|
||||
|
||||
// IptablesPreroutingChainName specifies an iptables `PREROUTING` chain,
|
||||
// responsible for packets that just arrived at the network interface.
|
||||
IptablesPreroutingChainName = "PREROUTING"
|
||||
IptablesOutputChainName = "OUTPUT"
|
||||
|
||||
// IptablesOutputChainName specifies an iptables `OUTPUT` chain.
|
||||
IptablesOutputChainName = "OUTPUT"
|
||||
)
|
||||
|
||||
var (
|
||||
// ExecutionTraceID provides a unique identifier for this script's execution.
|
||||
ExecutionTraceID = strconv.Itoa(int(time.Now().Unix()))
|
||||
)
|
||||
|
||||
// FirewallConfiguration specifies how to configure a pod's iptables.
|
||||
type FirewallConfiguration struct {
|
||||
Mode string
|
||||
PortsToRedirectInbound []int
|
||||
|
|
|
@ -20,6 +20,7 @@ const (
|
|||
)
|
||||
|
||||
type (
|
||||
// Server encapsulates the Linkerd control plane's web dashboard server.
|
||||
Server struct {
|
||||
templateDir string
|
||||
staticDir string
|
||||
|
@ -52,6 +53,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
s.router.ServeHTTP(w, req)
|
||||
}
|
||||
|
||||
// NewServer returns an initialized `http.Server`, configured to listen on an
|
||||
// address, render templates, and serve static assets, for a given Linkerd
|
||||
// control plane.
|
||||
func NewServer(addr, templateDir, staticDir, uuid, controllerNamespace string, singleNamespace bool, webpackDevServer string, reload bool, apiClient pb.ApiClient) *http.Server {
|
||||
server := &Server{
|
||||
templateDir: templateDir,
|
||||
|
@ -118,6 +122,8 @@ func NewServer(addr, templateDir, staticDir, uuid, controllerNamespace string, s
|
|||
return httpServer
|
||||
}
|
||||
|
||||
// RenderTemplate writes a rendered template into a buffer, given an HTTP
|
||||
// request and template information.
|
||||
func (s *Server) RenderTemplate(w http.ResponseWriter, templateFile, templateName string, args interface{}) error {
|
||||
log.Debugf("emitting template %s", templateFile)
|
||||
template, err := s.loadTemplate(templateFile)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package srv
|
||||
|
||||
// FakeServer provides a mock of a Server in `/web/srv`.
|
||||
func FakeServer() Server {
|
||||
return Server{
|
||||
templateDir: "../templates",
|
||||
|
|
Loading…
Reference in New Issue