Auto-update dependencies (#88)

Produced via:
  `dep ensure -update knative.dev/test-infra knative.dev/pkg`
/assign mattmoor
This commit is contained in:
mattmoor-sockpuppet 2019-09-03 12:04:05 -07:00 committed by Knative Prow Robot
parent ba3627dfdd
commit 2c930e11d9
14 changed files with 215 additions and 68 deletions

4
Gopkg.lock generated
View File

@ -927,7 +927,7 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:999e5842e5917fc452ae40769030dbc049e9def569118d01804f0fc46956e4fa" digest = "1:304324ba78e40393c43cdb4ad511a77524d044dc6feaad60eadd37abb68e2c1f"
name = "knative.dev/pkg" name = "knative.dev/pkg"
packages = [ packages = [
"apis", "apis",
@ -946,7 +946,7 @@
"metrics/metricskey", "metrics/metricskey",
] ]
pruneopts = "T" pruneopts = "T"
revision = "8cae700d29e47d30cbc05ffb230a5e8d73aaec9e" revision = "6c69e99ee3701aac3ac8470a850eb6cd73796c74"
[[projects]] [[projects]]
branch = "master" branch = "master"

View File

@ -37,8 +37,12 @@ type Key struct{}
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
c := client.Get(ctx) c := client.Get(ctx)
opts := make([]externalversions.SharedInformerOption, 0, 1)
if injection.HasNamespaceScope(ctx) {
opts = append(opts, externalversions.WithNamespace(injection.GetNamespaceScope(ctx)))
}
return context.WithValue(ctx, Key{}, return context.WithValue(ctx, Key{},
externalversions.NewSharedInformerFactory(c, controller.GetResyncPeriod(ctx))) externalversions.NewSharedInformerFactoryWithOptions(c, controller.GetResyncPeriod(ctx), opts...))
} }
// Get extracts the InformerFactory from the context. // Get extracts the InformerFactory from the context.

View File

@ -36,6 +36,10 @@ func init() {
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
c := fake.Get(ctx) c := fake.Get(ctx)
opts := make([]externalversions.SharedInformerOption, 0, 1)
if injection.HasNamespaceScope(ctx) {
opts = append(opts, externalversions.WithNamespace(injection.GetNamespaceScope(ctx)))
}
return context.WithValue(ctx, factory.Key{}, return context.WithValue(ctx, factory.Key{},
externalversions.NewSharedInformerFactory(c, controller.GetResyncPeriod(ctx))) externalversions.NewSharedInformerFactoryWithOptions(c, controller.GetResyncPeriod(ctx), opts...))
} }

View File

@ -64,11 +64,15 @@ func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w i
klog.V(5).Infof("processing type %v", t) klog.V(5).Infof("processing type %v", t)
m := map[string]interface{}{ m := map[string]interface{}{
"cachingClientGet": c.Universe.Type(types.Name{Package: g.cachingClientSetPackage, Name: "Get"}), "cachingClientGet": c.Universe.Type(types.Name{Package: g.cachingClientSetPackage, Name: "Get"}),
"informersNewSharedInformerFactory": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "NewSharedInformerFactory"}), "informersNewSharedInformerFactoryWithOptions": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "NewSharedInformerFactoryWithOptions"}),
"informersSharedInformerFactory": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "SharedInformerFactory"}), "informersSharedInformerOption": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "SharedInformerOption"}),
"injectionRegisterInformerFactory": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterInformerFactory"}), "informersWithNamespace": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "WithNamespace"}),
"controllerGetResyncPeriod": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "GetResyncPeriod"}), "informersSharedInformerFactory": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "SharedInformerFactory"}),
"injectionRegisterInformerFactory": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterInformerFactory"}),
"injectionHasNamespace": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "HasNamespaceScope"}),
"injectionGetNamespace": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "GetNamespaceScope"}),
"controllerGetResyncPeriod": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "GetResyncPeriod"}),
"loggingFromContext": c.Universe.Function(types.Name{ "loggingFromContext": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/logging", Package: "knative.dev/pkg/logging",
Name: "FromContext", Name: "FromContext",
@ -90,8 +94,12 @@ type Key struct{}
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
c := {{.cachingClientGet|raw}}(ctx) c := {{.cachingClientGet|raw}}(ctx)
opts := make([]{{.informersSharedInformerOption|raw}}, 0, 1)
if {{.injectionHasNamespace|raw}}(ctx) {
opts = append(opts, {{.informersWithNamespace|raw}}({{.injectionGetNamespace|raw}}(ctx)))
}
return context.WithValue(ctx, Key{}, return context.WithValue(ctx, Key{},
{{.informersNewSharedInformerFactory|raw}}(c, {{.controllerGetResyncPeriod|raw}}(ctx))) {{.informersNewSharedInformerFactoryWithOptions|raw}}(c, {{.controllerGetResyncPeriod|raw}}(ctx), opts...))
} }
// Get extracts the InformerFactory from the context. // Get extracts the InformerFactory from the context.

View File

@ -66,14 +66,18 @@ func (g *fakeFactoryGenerator) GenerateType(c *generator.Context, t *types.Type,
klog.V(5).Infof("processing type %v", t) klog.V(5).Infof("processing type %v", t)
m := map[string]interface{}{ m := map[string]interface{}{
"factoryKey": c.Universe.Type(types.Name{Package: g.factoryInjectionPkg, Name: "Key"}), "factoryKey": c.Universe.Type(types.Name{Package: g.factoryInjectionPkg, Name: "Key"}),
"factoryGet": c.Universe.Function(types.Name{Package: g.factoryInjectionPkg, Name: "Get"}), "factoryGet": c.Universe.Function(types.Name{Package: g.factoryInjectionPkg, Name: "Get"}),
"clientGet": c.Universe.Function(types.Name{Package: g.fakeClientInjectionPkg, Name: "Get"}), "clientGet": c.Universe.Function(types.Name{Package: g.fakeClientInjectionPkg, Name: "Get"}),
"informersNewSharedInformerFactory": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "NewSharedInformerFactory"}), "informersNewSharedInformerFactoryWithOptions": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "NewSharedInformerFactoryWithOptions"}),
"informersSharedInformerOption": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "SharedInformerOption"}),
"informersWithNamespace": c.Universe.Function(types.Name{Package: g.sharedInformerFactoryPackage, Name: "WithNamespace"}),
"injectionRegisterInformerFactory": c.Universe.Function(types.Name{ "injectionRegisterInformerFactory": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/injection", Package: "knative.dev/pkg/injection",
Name: "Fake.RegisterInformerFactory", Name: "Fake.RegisterInformerFactory",
}), }),
"injectionHasNamespace": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "HasNamespaceScope"}),
"injectionGetNamespace": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "GetNamespaceScope"}),
"controllerGetResyncPeriod": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "GetResyncPeriod"}), "controllerGetResyncPeriod": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "GetResyncPeriod"}),
} }
@ -91,7 +95,11 @@ func init() {
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
c := {{.clientGet|raw}}(ctx) c := {{.clientGet|raw}}(ctx)
opts := make([]{{.informersSharedInformerOption|raw}}, 0, 1)
if {{.injectionHasNamespace|raw}}(ctx) {
opts = append(opts, {{.informersWithNamespace|raw}}({{.injectionGetNamespace|raw}}(ctx)))
}
return context.WithValue(ctx, {{.factoryKey|raw}}{}, return context.WithValue(ctx, {{.factoryKey|raw}}{},
{{.informersNewSharedInformerFactory|raw}}(c, {{.controllerGetResyncPeriod|raw}}(ctx))) {{.informersNewSharedInformerFactoryWithOptions|raw}}(c, {{.controllerGetResyncPeriod|raw}}(ctx), opts...))
} }
` `

View File

@ -0,0 +1,49 @@
/*
Copyright 2019 The Knative Authors
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.
*/
package injection
import (
"context"
)
// nsKey is the key that namespaces are associated with on
// contexts returned by WithNamespaceScope.
type nsKey struct{}
// WithNamespaceScope associates a namespace scoping with the
// provided context, which will scope the informers produced
// by the downstream informer factories.
func WithNamespaceScope(ctx context.Context, namespace string) context.Context {
return context.WithValue(ctx, nsKey{}, namespace)
}
// HasNamespaceScope determines whether the provided context has
// been scoped to a particular namespace.
func HasNamespaceScope(ctx context.Context) bool {
return GetNamespaceScope(ctx) != ""
}
// GetNamespaceScope accesses the namespace associated with the
// provided context. This should be called when the injection
// logic is setting up shared informer factories.
func GetNamespaceScope(ctx context.Context) string {
value := ctx.Value(nsKey{})
if value == nil {
return ""
}
return value.(string)
}

View File

@ -65,4 +65,41 @@ limitations under the License.
// dave.NewController, // dave.NewController,
// ) // )
// } // }
//
// If you want to adapt the above to run the controller within a single
// namespace, you can instead do something like:
//
// package main
//
// import (
// // The set of controllers this controller process runs.
// // Linking these will register their transitive dependencies, after
// // which the shared main can set up the rest.
// "github.com/knative/foo/pkg/reconciler/matt"
// "github.com/knative/foo/pkg/reconciler/scott"
// "github.com/knative/foo/pkg/reconciler/ville"
// "github.com/knative/foo/pkg/reconciler/dave"
//
// // This defines the shared main for injected controllers.
// "knative.dev/pkg/injection/sharedmain"
//
// // These are used to set up the context.
// "knative.dev/pkg/injection"
// "knative.dev/pkg/signals"
// )
//
// func main() {
// // Scope the shared informer factories to the provided namespace.
// ctx := injection.WithNamespace(signals.NewContext(), "the-namespace")
//
// // Use our initial context when setting up the controllers.
// sharedmain.MainWithContext(ctx, "mycomponent",
// // We pass in the list of controllers to construct, and that's it!
// // If we forget to add this, go will complain about the unused import.
// matt.NewController,
// scott.NewController,
// ville.NewController,
// dave.NewController,
// )
// }
package injection package injection

View File

@ -38,8 +38,12 @@ type Key struct{}
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
axc := apiextclient.Get(ctx) axc := apiextclient.Get(ctx)
opts := make([]informers.SharedInformerOption, 0, 1)
if injection.HasNamespaceScope(ctx) {
opts = append(opts, informers.WithNamespace(injection.GetNamespaceScope(ctx)))
}
return context.WithValue(ctx, Key{}, return context.WithValue(ctx, Key{},
informers.NewSharedInformerFactory(axc, controller.GetResyncPeriod(ctx))) informers.NewSharedInformerFactoryWithOptions(axc, controller.GetResyncPeriod(ctx), opts...))
} }
// Get extracts the Kubernetes Api Extensions InformerFactory from the context. // Get extracts the Kubernetes Api Extensions InformerFactory from the context.

View File

@ -35,6 +35,10 @@ func init() {
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
kc := fake.Get(ctx) kc := fake.Get(ctx)
opts := make([]informers.SharedInformerOption, 0, 1)
if injection.HasNamespaceScope(ctx) {
opts = append(opts, informers.WithNamespace(injection.GetNamespaceScope(ctx)))
}
return context.WithValue(ctx, factory.Key{}, return context.WithValue(ctx, factory.Key{},
informers.NewSharedInformerFactory(kc, controller.GetResyncPeriod(ctx))) informers.NewSharedInformerFactoryWithOptions(kc, controller.GetResyncPeriod(ctx), opts...))
} }

View File

@ -37,8 +37,12 @@ type Key struct{}
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
kc := kubeclient.Get(ctx) kc := kubeclient.Get(ctx)
opts := make([]informers.SharedInformerOption, 0, 1)
if injection.HasNamespaceScope(ctx) {
opts = append(opts, informers.WithNamespace(injection.GetNamespaceScope(ctx)))
}
return context.WithValue(ctx, Key{}, return context.WithValue(ctx, Key{},
informers.NewSharedInformerFactory(kc, controller.GetResyncPeriod(ctx))) informers.NewSharedInformerFactoryWithOptions(kc, controller.GetResyncPeriod(ctx), opts...))
} }
// Get extracts the Kubernetes InformerFactory from the context. // Get extracts the Kubernetes InformerFactory from the context.

View File

@ -35,6 +35,10 @@ func init() {
func withInformerFactory(ctx context.Context) context.Context { func withInformerFactory(ctx context.Context) context.Context {
kc := fake.Get(ctx) kc := fake.Get(ctx)
opts := make([]informers.SharedInformerOption, 0, 1)
if injection.HasNamespaceScope(ctx) {
opts = append(opts, informers.WithNamespace(injection.GetNamespaceScope(ctx)))
}
return context.WithValue(ctx, factory.Key{}, return context.WithValue(ctx, factory.Key{},
informers.NewSharedInformerFactory(kc, controller.GetResyncPeriod(ctx))) informers.NewSharedInformerFactoryWithOptions(kc, controller.GetResyncPeriod(ctx), opts...))
} }

View File

@ -20,6 +20,7 @@ package test
import ( import (
"fmt" "fmt"
"net/http"
"strings" "strings"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
@ -38,8 +39,8 @@ type KubeClient struct {
} }
// NewSpoofingClient returns a spoofing client to make requests // NewSpoofingClient returns a spoofing client to make requests
func NewSpoofingClient(client *KubeClient, logf logging.FormatLogger, domain string, resolvable bool) (*spoof.SpoofingClient, error) { func NewSpoofingClient(client *KubeClient, transport *http.Transport, logf logging.FormatLogger, domain string, resolvable bool) (*spoof.SpoofingClient, error) {
return spoof.New(client.Kube, logf, domain, resolvable, Flags.IngressEndpoint) return spoof.New(client.Kube, transport, logf, domain, resolvable, Flags.IngressEndpoint)
} }
// NewKubeClient instantiates and returns several clientsets required for making request to the // NewKubeClient instantiates and returns several clientsets required for making request to the

View File

@ -74,7 +74,7 @@ func IsOneOfStatusCodes(codes ...int) spoof.ResponseChecker {
} }
} }
return true, fmt.Errorf("status = %d, want one of: %v", resp.StatusCode, codes) return true, fmt.Errorf("status = %d %s, want one of: %v", resp.StatusCode, resp.Status, codes)
} }
} }
@ -134,8 +134,15 @@ func MatchesAllOf(checkers ...spoof.ResponseChecker) spoof.ResponseChecker {
// the domain in the request headers, otherwise it will make the request directly to domain. // the domain in the request headers, otherwise it will make the request directly to domain.
// desc will be used to name the metric that is emitted to track how long it took for the // desc will be used to name the metric that is emitted to track how long it took for the
// domain to get into the state checked by inState. Commas in `desc` must be escaped. // domain to get into the state checked by inState. Commas in `desc` must be escaped.
func WaitForEndpointState(kubeClient *KubeClient, logf logging.FormatLogger, theURL string, inState spoof.ResponseChecker, desc string, resolvable bool, opts ...RequestOption) (*spoof.Response, error) { func WaitForEndpointState(
return WaitForEndpointStateWithTimeout(kubeClient, logf, theURL, inState, desc, resolvable, spoof.RequestTimeout, opts...) kubeClient *KubeClient,
logf logging.FormatLogger,
theURL string,
inState spoof.ResponseChecker,
desc string,
resolvable bool,
opts ...RequestOption) (*spoof.Response, error) {
return WaitForEndpointStateWithTimeout(kubeClient, http.DefaultTransport.(*http.Transport), logf, theURL, inState, desc, resolvable, spoof.RequestTimeout, opts...)
} }
// WaitForEndpointStateWithTimeout will poll an endpoint until inState indicates the state is achieved // WaitForEndpointStateWithTimeout will poll an endpoint until inState indicates the state is achieved
@ -145,8 +152,15 @@ func WaitForEndpointState(kubeClient *KubeClient, logf logging.FormatLogger, the
// desc will be used to name the metric that is emitted to track how long it took for the // desc will be used to name the metric that is emitted to track how long it took for the
// domain to get into the state checked by inState. Commas in `desc` must be escaped. // domain to get into the state checked by inState. Commas in `desc` must be escaped.
func WaitForEndpointStateWithTimeout( func WaitForEndpointStateWithTimeout(
kubeClient *KubeClient, logf logging.FormatLogger, theURL string, inState spoof.ResponseChecker, kubeClient *KubeClient,
desc string, resolvable bool, timeout time.Duration, opts ...RequestOption) (*spoof.Response, error) { transport *http.Transport,
logf logging.FormatLogger,
theURL string,
inState spoof.ResponseChecker,
desc string,
resolvable bool,
timeout time.Duration,
opts ...RequestOption) (*spoof.Response, error) {
defer logging.GetEmitableSpan(context.Background(), fmt.Sprintf("WaitForEndpointState/%s", desc)).End() defer logging.GetEmitableSpan(context.Background(), fmt.Sprintf("WaitForEndpointState/%s", desc)).End()
// Try parsing the "theURL" with and without a scheme. // Try parsing the "theURL" with and without a scheme.
@ -167,7 +181,7 @@ func WaitForEndpointStateWithTimeout(
opt(req) opt(req)
} }
client, err := NewSpoofingClient(kubeClient, logf, asURL.Hostname(), resolvable) client, err := NewSpoofingClient(kubeClient, transport, logf, asURL.Hostname(), resolvable)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -19,9 +19,12 @@ limitations under the License.
package spoof package spoof
import ( import (
"context"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -82,72 +85,75 @@ type SpoofingClient struct {
RequestInterval time.Duration RequestInterval time.Duration
RequestTimeout time.Duration RequestTimeout time.Duration
endpoint string
domain string
logf logging.FormatLogger logf logging.FormatLogger
} }
// New returns a SpoofingClient that rewrites requests if the target domain is not `resolveable`. // New returns a SpoofingClient that rewrites requests if the target domain is not `resolvable`.
// It does this by looking up the ingress at construction time, so reusing a client will not // It does this by looking up the ingress at construction time, so reusing a client will not
// follow the ingress if it moves (or if there are multiple ingresses). // follow the ingress if it moves (or if there are multiple ingresses).
// //
// If that's a problem, see test/request.go#WaitForEndpointState for oneshot spoofing. // If that's a problem, see test/request.go#WaitForEndpointState for oneshot spoofing.
func New(kubeClientset *kubernetes.Clientset, logf logging.FormatLogger, domain string, resolvable bool, endpointOverride string) (*SpoofingClient, error) { func New(
kubeClientset *kubernetes.Clientset,
transport *http.Transport,
logf logging.FormatLogger,
domain string,
resolvable bool,
endpointOverride string) (*SpoofingClient, error) {
// Spoof the hostname at the resolver level
endpoint, err := ResolveEndpoint(kubeClientset, domain, resolvable, endpointOverride)
if err != nil {
fmt.Errorf("failed get the cluster endpoint: %v", err)
}
oldDialContext := transport.DialContext
if oldDialContext == nil {
oldDialContext = (&net.Dialer{}).DialContext
}
transport.DialContext = func(ctx context.Context, network, addr string) (conn net.Conn, e error) {
spoofed := addr
if i := strings.LastIndex(addr, ":"); i != -1 && domain == addr[:i] {
// The original hostname:port is spoofed by replacing the hostname by the value
// returned by ResolveEndpoint.
spoofed = endpoint + ":" + addr[i+1:]
logf("Spoofing %s -> %s", addr, spoofed)
}
return oldDialContext(ctx, network, spoofed)
}
// Enable Zipkin tracing
roundTripper := &ochttp.Transport{
Base: transport,
Propagation: &b3.HTTPFormat{},
}
sc := SpoofingClient{ sc := SpoofingClient{
Client: &http.Client{Transport: &ochttp.Transport{Propagation: &b3.HTTPFormat{}}}, // Using ochttp Transport required for zipkin-tracing Client: &http.Client{Transport: roundTripper},
RequestInterval: requestInterval, RequestInterval: requestInterval,
RequestTimeout: RequestTimeout, RequestTimeout: RequestTimeout,
logf: logf, logf: logf,
} }
var err error
if sc.endpoint, err = ResolveEndpoint(kubeClientset, domain, resolvable, endpointOverride); err != nil {
return nil, err
}
if !resolvable {
sc.domain = domain
}
return &sc, nil return &sc, nil
} }
// ResolveEndpoint resolves the endpoint address considering whether the domain is resolvable and taking into // ResolveEndpoint resolves the endpoint address considering whether the domain is resolvable and taking into
// account whether the user overrode the endpoint address externally // account whether the user overrode the endpoint address externally
func ResolveEndpoint(kubeClientset *kubernetes.Clientset, domain string, resolvable bool, endpointOverride string) (string, error) { func ResolveEndpoint(kubeClientset *kubernetes.Clientset, domain string, resolvable bool, endpointOverride string) (string, error) {
// If the domain is resolvable, we can use it directly when we make requests. // If the domain is resolvable, it can be used directly
endpoint := domain if resolvable {
if !resolvable { return domain, nil
e := endpointOverride
if endpointOverride == "" {
var err error
// If the domain that the Route controller is configured to assign to Route.Status.Domain
// (the domainSuffix) is not resolvable, we need to retrieve the endpoint and spoof
// the Host in our requests.
if e, err = ingress.GetIngressEndpoint(kubeClientset); err != nil {
return "", err
}
}
endpoint = e
} }
return endpoint, nil // If an override is provided, use it
if endpointOverride != "" {
return endpointOverride, nil
}
// Otherwise, use the actual cluster endpoint
return ingress.GetIngressEndpoint(kubeClientset)
} }
// Do dispatches to the underlying http.Client.Do, spoofing domains as needed // Do dispatches to the underlying http.Client.Do, spoofing domains as needed
// and transforming the http.Response into a spoof.Response. // and transforming the http.Response into a spoof.Response.
// Each response is augmented with "ZipkinTraceID" header that identifies the zipkin trace corresponding to the request. // Each response is augmented with "ZipkinTraceID" header that identifies the zipkin trace corresponding to the request.
func (sc *SpoofingClient) Do(req *http.Request) (*Response, error) { func (sc *SpoofingClient) Do(req *http.Request) (*Response, error) {
// Controls the Host header, for spoofing.
if sc.domain != "" {
req.Host = sc.domain
}
// Controls the actual resolution.
if sc.endpoint != "" {
req.URL.Host = sc.endpoint
}
// Starting span to capture zipkin trace. // Starting span to capture zipkin trace.
traceContext, span := trace.StartSpan(req.Context(), "SpoofingClient-Trace") traceContext, span := trace.StartSpan(req.Context(), "SpoofingClient-Trace")
defer span.End() defer span.End()