diff --git a/apps/cnquery/cmd/login.go b/apps/cnquery/cmd/login.go index da5889ce92..92868e0f61 100644 --- a/apps/cnquery/cmd/login.go +++ b/apps/cnquery/cmd/login.go @@ -19,6 +19,7 @@ import ( cnquery_providers "go.mondoo.com/cnquery/v10/providers" "go.mondoo.com/cnquery/v10/providers-sdk/v1/sysinfo" "go.mondoo.com/cnquery/v10/providers-sdk/v1/upstream" + rangerUtils "go.mondoo.com/cnquery/v10/utils/ranger" "go.mondoo.com/ranger-rpc" "go.mondoo.com/ranger-rpc/codes" "go.mondoo.com/ranger-rpc/plugins/authentication/statictoken" @@ -72,7 +73,7 @@ func register(token string, annotations map[string]string, timer int, splay int) if err != nil { return cli_errors.NewCommandError(errors.Wrap(err, "could not gather client information"), 1) } - defaultPlugins := defaultRangerPlugins(sysInfo, cnquery.DefaultFeatures) + defaultPlugins := rangerUtils.DefaultRangerPlugins(cnquery.DefaultFeatures) apiEndpoint := viper.GetString("api_endpoint") token = strings.TrimSpace(token) diff --git a/apps/cnquery/cmd/logout.go b/apps/cnquery/cmd/logout.go index 08dd8c0045..d308406d68 100644 --- a/apps/cnquery/cmd/logout.go +++ b/apps/cnquery/cmd/logout.go @@ -14,8 +14,8 @@ import ( "go.mondoo.com/cnquery/v10/cli/config" cli_errors "go.mondoo.com/cnquery/v10/cli/errors" cnquery_providers "go.mondoo.com/cnquery/v10/providers" - "go.mondoo.com/cnquery/v10/providers-sdk/v1/sysinfo" "go.mondoo.com/cnquery/v10/providers-sdk/v1/upstream" + rangerUtils "go.mondoo.com/cnquery/v10/utils/ranger" "sigs.k8s.io/yaml" ) @@ -48,19 +48,13 @@ ensure the credentials cannot be used in the future. // print the used config to the user config.DisplayUsedConfig() - // determine information about the client - sysInfo, err := sysinfo.Get() - if err != nil { - return errors.Wrap(err, "could not gather client information") - } - // check valid client authentication serviceAccount := opts.GetServiceCredential() if serviceAccount == nil { return cli_errors.NewCommandError(errors.Wrap(err, "could not initialize client authentication"), ConfigurationErrorCode) } - plugins := defaultRangerPlugins(sysInfo, opts.GetFeatures()) + plugins := rangerUtils.DefaultRangerPlugins(opts.GetFeatures()) certAuth, err := upstream.NewServiceAccountRangerPlugin(serviceAccount) if err != nil { log.Error().Err(err).Msg("could not initialize client authentication") diff --git a/apps/cnquery/cmd/root.go b/apps/cnquery/cmd/root.go index 48f0577c3b..8ea11b8ee4 100644 --- a/apps/cnquery/cmd/root.go +++ b/apps/cnquery/cmd/root.go @@ -4,7 +4,6 @@ package cmd import ( - "net/http" "os" "regexp" "strings" @@ -14,15 +13,11 @@ import ( "github.com/spf13/cobra" "github.com/spf13/cobra/doc" "github.com/spf13/viper" - "go.mondoo.com/cnquery/v10" "go.mondoo.com/cnquery/v10/cli/config" cli_errors "go.mondoo.com/cnquery/v10/cli/errors" "go.mondoo.com/cnquery/v10/cli/providers" "go.mondoo.com/cnquery/v10/cli/theme" "go.mondoo.com/cnquery/v10/logger" - "go.mondoo.com/cnquery/v10/providers-sdk/v1/sysinfo" - "go.mondoo.com/ranger-rpc" - "go.mondoo.com/ranger-rpc/plugins/scope" ) const ( @@ -138,38 +133,6 @@ func initLogger() { logger.Set(level) } -func defaultRangerPlugins(sysInfo *sysinfo.SystemInfo, features cnquery.Features) []ranger.ClientPlugin { - plugins := []ranger.ClientPlugin{} - plugins = append(plugins, scope.NewRequestIDRangerPlugin()) - plugins = append(plugins, sysInfoHeader(sysInfo, features)) - return plugins -} - -func sysInfoHeader(sysInfo *sysinfo.SystemInfo, features cnquery.Features) ranger.ClientPlugin { - const ( - HttpHeaderUserAgent = "User-Agent" - HttpHeaderClientFeatures = "Mondoo-Features" - HttpHeaderPlatformID = "Mondoo-PlatformID" - ) - - h := http.Header{} - info := map[string]string{ - "cnquery": cnquery.Version, - "build": cnquery.Build, - } - if sysInfo != nil { - info["PN"] = sysInfo.Platform.Name - info["PR"] = sysInfo.Platform.Version - info["PA"] = sysInfo.Platform.Arch - info["IP"] = sysInfo.IP - info["HN"] = sysInfo.Hostname - h.Set(HttpHeaderPlatformID, sysInfo.PlatformId) - } - h.Set(HttpHeaderUserAgent, scope.XInfoHeader(info)) - h.Set(HttpHeaderClientFeatures, features.Encode()) - return scope.NewCustomHeaderRangerPlugin(h) -} - var reMdName = regexp.MustCompile(`/([^/]+)\.md$`) func GenerateMarkdown(dir string) error { diff --git a/explorer/scan/local_scanner.go b/explorer/scan/local_scanner.go index 8af7b2399b..d7e2b9b853 100644 --- a/explorer/scan/local_scanner.go +++ b/explorer/scan/local_scanner.go @@ -227,7 +227,7 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up // plan scan jobs reporter := NewAggregateReporter() if job.Bundle == nil && upstream != nil && upstream.Creds != nil { - client, err := upstream.InitClient() + client, err := upstream.InitClient(ctx) if err != nil { return nil, err } @@ -271,7 +271,7 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up spaceMrn := "" var services *explorer.Services if upstream != nil && upstream.ApiEndpoint != "" && !upstream.Incognito { - client, err := upstream.InitClient() + client, err := upstream.InitClient(ctx) if err != nil { return nil, err } @@ -447,7 +447,7 @@ func (s *LocalScanner) runMotorizedAsset(job *AssetJob) (*AssetReport, error) { runtimeErr := inmemory.WithDb(job.runtime, func(db *inmemory.Db, services *explorer.LocalServices) error { if job.UpstreamConfig != nil && job.UpstreamConfig.ApiEndpoint != "" && !job.UpstreamConfig.Incognito { log.Debug().Msg("using API endpoint " + job.UpstreamConfig.ApiEndpoint) - client, err := job.UpstreamConfig.InitClient() + client, err := job.UpstreamConfig.InitClient(job.Ctx) if err != nil { return err } diff --git a/providers-sdk/v1/upstream/upstream.go b/providers-sdk/v1/upstream/upstream.go index dd46f89f26..75fa0537c6 100644 --- a/providers-sdk/v1/upstream/upstream.go +++ b/providers-sdk/v1/upstream/upstream.go @@ -4,12 +4,15 @@ package upstream import ( + "context" "errors" "net/http" "net/url" "github.com/rs/zerolog/log" + "go.mondoo.com/cnquery/v10" "go.mondoo.com/cnquery/v10/utils/multierr" + rangerUtils "go.mondoo.com/cnquery/v10/utils/ranger" "go.mondoo.com/ranger-rpc" guard_cert_auth "go.mondoo.com/ranger-rpc/plugins/authentication/cert" "go.mondoo.com/ranger-rpc/plugins/rangerguard/crypto" @@ -52,15 +55,17 @@ type UpstreamClient struct { HttpClient *http.Client } -func (c *UpstreamConfig) InitClient() (*UpstreamClient, error) { +func (c *UpstreamConfig) InitClient(ctx context.Context) (*UpstreamClient, error) { certAuth, err := NewServiceAccountRangerPlugin(c.Creds) if err != nil { return nil, multierr.Wrap(err, "could not initialize client authentication") } + plugins := []ranger.ClientPlugin{certAuth} + plugins = append(plugins, rangerUtils.DefaultRangerPlugins(cnquery.GetFeatures(ctx))...) res := UpstreamClient{ UpstreamConfig: *c, - Plugins: []ranger.ClientPlugin{certAuth}, + Plugins: plugins, HttpClient: c.httpClient(), } diff --git a/providers/arista/provider/provider.go b/providers/arista/provider/provider.go index 7cc0ded1f1..a16c75035c 100644 --- a/providers/arista/provider/provider.go +++ b/providers/arista/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "net/url" "strconv" @@ -132,7 +133,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/atlassian/provider/provider.go b/providers/atlassian/provider/provider.go index bc4edd4df0..d3afa23d97 100644 --- a/providers/atlassian/provider/provider.go +++ b/providers/atlassian/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "go.mondoo.com/cnquery/v10/llx" @@ -145,7 +146,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/aws/provider/provider.go b/providers/aws/provider/provider.go index 09996209e5..9dcb19458c 100644 --- a/providers/aws/provider/provider.go +++ b/providers/aws/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "strings" @@ -214,7 +215,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/azure/provider/provider.go b/providers/azure/provider/provider.go index 814584c633..7613b49dc0 100644 --- a/providers/azure/provider/provider.go +++ b/providers/azure/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "fmt" @@ -211,7 +212,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/core/provider/provider.go b/providers/core/provider/provider.go index b9cde5b7f4..09a1905afa 100644 --- a/providers/core/provider/provider.go +++ b/providers/core/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "go.mondoo.com/cnquery/v10/llx" @@ -40,7 +41,7 @@ func (s *Service) Connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient var err error if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/equinix/provider/provider.go b/providers/equinix/provider/provider.go index 98367b7294..7e0f43578c 100644 --- a/providers/equinix/provider/provider.go +++ b/providers/equinix/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "os" @@ -116,7 +117,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/gcp/provider/provider.go b/providers/gcp/provider/provider.go index 54a45107d4..0d80f30331 100644 --- a/providers/gcp/provider/provider.go +++ b/providers/gcp/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "os" @@ -229,7 +230,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/github/provider/provider.go b/providers/github/provider/provider.go index ac287dce54..6748c37af4 100644 --- a/providers/github/provider/provider.go +++ b/providers/github/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "os" "strings" @@ -135,7 +136,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/gitlab/provider/provider.go b/providers/gitlab/provider/provider.go index 2a8daa26e2..9768788cdb 100644 --- a/providers/gitlab/provider/provider.go +++ b/providers/gitlab/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "os" "strconv" @@ -149,7 +150,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/google-workspace/provider/provider.go b/providers/google-workspace/provider/provider.go index 310d83ba87..7fbdc4ae39 100644 --- a/providers/google-workspace/provider/provider.go +++ b/providers/google-workspace/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "os" @@ -167,7 +168,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/ipmi/provider/provider.go b/providers/ipmi/provider/provider.go index 27e5435e86..b7f320d932 100644 --- a/providers/ipmi/provider/provider.go +++ b/providers/ipmi/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "net/url" "strconv" @@ -126,7 +127,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/k8s/provider/provider.go b/providers/k8s/provider/provider.go index 49c2748863..51a18a71f5 100644 --- a/providers/k8s/provider/provider.go +++ b/providers/k8s/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "go.mondoo.com/cnquery/v10" @@ -164,7 +165,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/ms365/provider/provider.go b/providers/ms365/provider/provider.go index 590db3757f..f0a2f29808 100644 --- a/providers/ms365/provider/provider.go +++ b/providers/ms365/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory" @@ -123,7 +124,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/network/provider/provider.go b/providers/network/provider/provider.go index b6a4b3c965..a81d33038f 100644 --- a/providers/network/provider/provider.go +++ b/providers/network/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "net/url" "strings" @@ -167,7 +168,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient var err error if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/oci/provider/provider.go b/providers/oci/provider/provider.go index 960acf2414..cd5b1a4931 100644 --- a/providers/oci/provider/provider.go +++ b/providers/oci/provider/provider.go @@ -145,7 +145,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/okta/provider/provider.go b/providers/okta/provider/provider.go index d5d3ccdff9..97c85e4867 100644 --- a/providers/okta/provider/provider.go +++ b/providers/okta/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "os" "strings" @@ -125,7 +126,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/opcua/provider/provider.go b/providers/opcua/provider/provider.go index 943334e9cf..aa6d163cd5 100644 --- a/providers/opcua/provider/provider.go +++ b/providers/opcua/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "github.com/mozillazg/go-slugify" @@ -99,7 +100,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/os/provider/provider.go b/providers/os/provider/provider.go index 8078b657c6..2453117989 100644 --- a/providers/os/provider/provider.go +++ b/providers/os/provider/provider.go @@ -418,7 +418,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/slack/provider/provider.go b/providers/slack/provider/provider.go index ce92e40365..a210a91192 100644 --- a/providers/slack/provider/provider.go +++ b/providers/slack/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "os" @@ -136,7 +137,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/terraform/provider/provider.go b/providers/terraform/provider/provider.go index d22a06891a..e8b082161f 100644 --- a/providers/terraform/provider/provider.go +++ b/providers/terraform/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "strconv" @@ -170,7 +171,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/vcd/provider/provider.go b/providers/vcd/provider/provider.go index 91d74bacf3..43e8ec8dc6 100644 --- a/providers/vcd/provider/provider.go +++ b/providers/vcd/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "fmt" "strconv" @@ -117,7 +118,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/providers/vsphere/provider/provider.go b/providers/vsphere/provider/provider.go index 305c734f0e..b36f29815c 100644 --- a/providers/vsphere/provider/provider.go +++ b/providers/vsphere/provider/provider.go @@ -4,6 +4,7 @@ package provider import ( + "context" "errors" "net/url" "strconv" @@ -147,7 +148,7 @@ func (s *Service) connect(req *plugin.ConnectReq, callback plugin.ProviderCallba var upstream *upstream.UpstreamClient if req.Upstream != nil && !req.Upstream.Incognito { - upstream, err = req.Upstream.InitClient() + upstream, err = req.Upstream.InitClient(context.Background()) if err != nil { return nil, err } diff --git a/utils/ranger/plugins.go b/utils/ranger/plugins.go new file mode 100644 index 0000000000..1bf82f261e --- /dev/null +++ b/utils/ranger/plugins.go @@ -0,0 +1,44 @@ +// Copyright (c) Mondoo, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package ranger + +import ( + "net/http" + "runtime" + + "go.mondoo.com/cnquery/v10" + "go.mondoo.com/ranger-rpc" + "go.mondoo.com/ranger-rpc/plugins/scope" +) + +func DefaultRangerPlugins(features cnquery.Features) []ranger.ClientPlugin { + plugins := []ranger.ClientPlugin{} + plugins = append(plugins, scope.NewRequestIDRangerPlugin()) + plugins = append(plugins, sysInfoHeader(features)) + return plugins +} + +func sysInfoHeader(features cnquery.Features) ranger.ClientPlugin { + const ( + HttpHeaderUserAgent = "User-Agent" + HttpHeaderClientFeatures = "Mondoo-Features" + HttpHeaderPlatformID = "Mondoo-PlatformID" + ) + + h := http.Header{} + info := map[string]string{ + "cnquery": cnquery.Version, + "build": cnquery.Build, + } + info["PN"] = runtime.GOOS + // info["PR"] = sysInfo.Platform.Version + // info["PA"] = sysInfo.Platform.Arch + // info["IP"] = sysInfo.IP + // info["HN"] = sysInfo.Hostname + // h.Set(HttpHeaderPlatformID, sysInfo.PlatformId) + + h.Set(HttpHeaderUserAgent, scope.XInfoHeader(info)) + h.Set(HttpHeaderClientFeatures, features.Encode()) + return scope.NewCustomHeaderRangerPlugin(h) +}