Skip to content

Commit 7102dbb

Browse files
committed
chore:[CSENG-68] add ffg call
chore:[CSENG-68] correct ffg path in fake server chore:[CSENG-68] update ffg hidden end point chore: [CSENG-68] plug in ffg call chore: [CSENG-68] update package chore: [CSENG-68] correct org chore: code tidy for CSENG-68 chore: update to use makeRequest chore: update tap tests [CSENG-68] chore: remove status check for CSENG-68 chore: implement ffg for otel [CSENG-68] chore: correct go mod [CSENG-68] chore: revert to standard http client lib [CSENG-68] chore: correct ffg unit test [CSENG-68] chore: lint service [CSENG-68]
1 parent fec68c6 commit 7102dbb

File tree

23 files changed

+957
-64
lines changed

23 files changed

+957
-64
lines changed

cliv2/cmd/cliv2/main.go

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package main
22

33
// !!! This import needs to be the first import, please do not change this !!!
4-
import _ "github.com/snyk/go-application-framework/pkg/networking/fips_enable"
5-
64
import (
75
"context"
86
"encoding/json"
@@ -25,19 +23,20 @@ import (
2523
"github.com/snyk/cli-extension-mcp-scan/pkg/mcpscan"
2624
"github.com/snyk/cli-extension-os-flows/pkg/osflows"
2725
"github.com/snyk/cli-extension-sbom/pkg/sbom"
28-
"github.com/snyk/container-cli/pkg/container"
29-
"github.com/snyk/error-catalog-golang-public/cli"
30-
"github.com/spf13/cobra"
31-
"github.com/spf13/pflag"
32-
3326
"github.com/snyk/cli/cliv2/cmd/cliv2/behavior/legacy"
3427
"github.com/snyk/cli/cliv2/internal/cliv2"
3528
"github.com/snyk/cli/cliv2/internal/constants"
29+
featureflaggateway "github.com/snyk/cli/cliv2/internal/feature-flag-gateway"
30+
"github.com/snyk/container-cli/pkg/container"
31+
"github.com/snyk/error-catalog-golang-public/cli"
3632
"github.com/snyk/go-application-framework/pkg/analytics"
3733
"github.com/snyk/go-application-framework/pkg/app"
3834
"github.com/snyk/go-application-framework/pkg/configuration"
3935
"github.com/snyk/go-application-framework/pkg/instrumentation"
4036
"github.com/snyk/go-application-framework/pkg/logging"
37+
_ "github.com/snyk/go-application-framework/pkg/networking/fips_enable"
38+
"github.com/spf13/cobra"
39+
"github.com/spf13/pflag"
4140

4241
cliv2utils "github.com/snyk/cli/cliv2/internal/utils"
4342

@@ -46,7 +45,6 @@ import (
4645
"github.com/snyk/go-application-framework/pkg/local_workflows/network_utils"
4746

4847
workflows "github.com/snyk/go-application-framework/pkg/local_workflows/connectivity_check_extension"
49-
5048
"github.com/snyk/go-httpauth/pkg/httpauth"
5149
"github.com/snyk/snyk-iac-capture/pkg/capture"
5250

@@ -59,7 +57,6 @@ import (
5957
"github.com/snyk/go-application-framework/pkg/workflow"
6058

6159
snykls "github.com/snyk/snyk-ls/ls_extension"
62-
6360
"github.com/snyk/studio-mcp/pkg/mcp"
6461

6562
cli_errors "github.com/snyk/cli/cliv2/internal/errors"
@@ -77,10 +74,11 @@ var scrubbedLogger logging.ScrubbingLogWriter
7774
var interactionId = instrumentation.AssembleUrnFromUUID(uuid.NewString())
7875

7976
const (
80-
unknownCommandMessage string = "unknown command"
81-
disable_analytics_flag string = "DISABLE_ANALYTICS"
82-
debug_level_flag string = "log-level"
83-
integrationNameFlag string = "integration-name"
77+
unknownCommandMessage string = "unknown command"
78+
disable_analytics_flag string = "DISABLE_ANALYTICS"
79+
debug_level_flag string = "log-level"
80+
integrationNameFlag string = "integration-name"
81+
showMavenBuildScopeFlag string = "show-maven-build-scope"
8482
)
8583

8684
type JsonErrorStruct struct {
@@ -591,6 +589,14 @@ func MainWithErrorCode() int {
591589
// add workflows as commands
592590
createCommandsForWorkflows(rootCommand, globalEngine)
593591

592+
// fetch feature flags
593+
ffgService, err := featureflaggateway.NewService(globalConfiguration.GetUrl(configuration.API_URL), 10*time.Second)
594+
if err != nil {
595+
globalLogger.Print("Failed to fetch feature flags", err)
596+
return constants.SNYK_EXIT_CODE_ERROR
597+
}
598+
apiToken := globalConfiguration.GetString(configuration.AUTHENTICATION_TOKEN)
599+
594600
// init Analytics
595601
cliAnalytics := globalEngine.GetAnalytics()
596602
cliAnalytics.SetVersion(cliv2.GetFullVersion())
@@ -601,6 +607,8 @@ func MainWithErrorCode() int {
601607
cliAnalytics.GetInstrumentation().SetCategory(instrumentation.DetermineCategory(os.Args, globalEngine))
602608
cliAnalytics.GetInstrumentation().SetStage(instrumentation.DetermineStage(cliAnalytics.IsCiEnvironment()))
603609
cliAnalytics.GetInstrumentation().SetStatus(analytics.Success)
610+
cliAnalytics.GetInstrumentation().AddExtension(showMavenBuildScopeFlag,
611+
IsFeatureEnabled(ctx, ffgService, globalConfiguration.GetString(configuration.ORGANIZATION), showMavenBuildScopeFlag, apiToken))
604612

605613
setTimeout(globalConfiguration, func() {
606614
os.Exit(constants.SNYK_EXIT_CODE_EX_UNAVAILABLE)
@@ -659,6 +667,26 @@ func MainWithErrorCode() int {
659667
return exitCode
660668
}
661669

670+
func IsFeatureEnabled(
671+
ctx context.Context,
672+
service featureflaggateway.Service,
673+
orgID string,
674+
flag string,
675+
token string,
676+
) bool {
677+
resp, err := service.EvaluateFlags(ctx, []string{flag}, orgID, "2024-10-15", token)
678+
if err != nil || resp == nil {
679+
return false
680+
}
681+
evals := resp.Data.Attributes.Evaluations
682+
for _, e := range evals {
683+
if e.Key == flag {
684+
return e.Value
685+
}
686+
}
687+
return false
688+
}
689+
662690
func legacyCLITerminated(err error, errorList []error) error {
663691
exitErr, isExitError := err.(*exec.ExitError)
664692
if isExitError && exitErr.ExitCode() == constants.SNYK_EXIT_CODE_TS_CLI_TERMINATED {

cliv2/go.mod

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ require (
6060
github.com/beorn7/perks v1.0.1 // indirect
6161
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
6262
github.com/bmatcuk/doublestar v1.3.4 // indirect
63-
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
63+
github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect
6464
github.com/cenkalti/backoff/v5 v5.0.2 // indirect
6565
github.com/cespare/xxhash/v2 v2.3.0 // indirect
6666
github.com/charmbracelet/bubbles v0.14.0 // indirect
@@ -99,7 +99,7 @@ require (
9999
github.com/go-git/go-billy/v5 v5.6.2 // indirect
100100
github.com/go-git/go-git/v5 v5.15.0 // indirect
101101
github.com/go-ini/ini v1.67.0 // indirect
102-
github.com/go-logr/logr v1.4.2 // indirect
102+
github.com/go-logr/logr v1.4.3 // indirect
103103
github.com/go-logr/stdr v1.2.2 // indirect
104104
github.com/go-ole/go-ole v1.3.0 // indirect
105105
github.com/go-playground/locales v0.14.1 // indirect
@@ -218,11 +218,11 @@ require (
218218
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect
219219
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
220220
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
221-
go.opentelemetry.io/otel v1.34.0 // indirect
222-
go.opentelemetry.io/otel/metric v1.34.0 // indirect
223-
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
224-
go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect
225-
go.opentelemetry.io/otel/trace v1.34.0 // indirect
221+
go.opentelemetry.io/otel v1.37.0 // indirect
222+
go.opentelemetry.io/otel/metric v1.37.0 // indirect
223+
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
224+
go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
225+
go.opentelemetry.io/otel/trace v1.37.0 // indirect
226226
go.uber.org/multierr v1.11.0 // indirect
227227
golang.org/x/crypto v0.45.0 // indirect
228228
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect

cliv2/go.sum

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ
691691
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
692692
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
693693
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
694-
github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
695-
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
694+
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
695+
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
696696
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
697697
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
698698
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
@@ -880,8 +880,8 @@ github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I
880880
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
881881
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=
882882
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
883-
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
884-
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
883+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
884+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
885885
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
886886
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
887887
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
@@ -1444,22 +1444,22 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.5
14441444
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
14451445
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
14461446
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
1447-
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
1448-
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
1447+
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
1448+
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
14491449
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
14501450
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
14511451
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
14521452
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw=
14531453
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc=
14541454
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I=
1455-
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
1456-
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
1457-
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
1458-
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
1459-
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
1460-
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
1461-
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
1462-
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
1455+
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
1456+
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
1457+
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
1458+
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
1459+
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
1460+
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
1461+
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
1462+
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
14631463
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
14641464
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
14651465
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package featureflaggateway
2+
3+
// FeatureFlagRequest request body for feature flag request.
4+
type FeatureFlagRequest struct {
5+
Data FeatureFlagsData `json:"data"`
6+
}
7+
8+
// FeatureFlagsData represents feature flags response data.
9+
type FeatureFlagsData struct {
10+
Type string `json:"type"`
11+
Attributes FeatureFlagsRequestAttributes `json:"attributes"`
12+
}
13+
14+
// FeatureFlagsRequestAttributes represents feature flags request attributes.
15+
type FeatureFlagsRequestAttributes struct {
16+
Flags []string `json:"flags"`
17+
}
18+
19+
// FeatureFlagsResponse represents the updated response format.
20+
type FeatureFlagsResponse struct {
21+
Data FeatureFlagsDataItem `json:"data"`
22+
}
23+
24+
// FeatureFlagsDataItem represents the "data" object (previously slice).
25+
type FeatureFlagsDataItem struct {
26+
ID string `json:"id"`
27+
Type string `json:"type"`
28+
Attributes FeatureFlagAttributesList `json:"attributes"`
29+
}
30+
31+
// FeatureFlagAttributesList represents attributes containing evaluations + evaluated_at.
32+
type FeatureFlagAttributesList struct {
33+
Evaluations []FeatureFlagAttributes `json:"evaluations"`
34+
EvaluatedAt string `json:"evaluatedAt"`
35+
}
36+
37+
// FeatureFlagAttributes represent one evaluation result.
38+
type FeatureFlagAttributes struct {
39+
Key string `json:"key"`
40+
Value bool `json:"value"`
41+
Reason string `json:"reason"`
42+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package featureflaggateway
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"encoding/json"
7+
"errors"
8+
"fmt"
9+
"net/http"
10+
"net/url"
11+
"path"
12+
"strings"
13+
"time"
14+
)
15+
16+
const (
17+
// ApplicationJSON is the content type for JSON.
18+
ApplicationJSON = "application/json"
19+
userAgent = "User-Agent"
20+
contentType = "Content-Type"
21+
accept = "Accept"
22+
snykCli = "snyk-cli"
23+
authorization = "Authorization"
24+
defaultVersion = "2024-10-15"
25+
)
26+
27+
// Service is a service for interacting with Feature Flag Gateway.
28+
type Service interface {
29+
EvaluateFlags(ctx context.Context, flags []string, orgID string, version string, token string) (*FeatureFlagsResponse, error)
30+
}
31+
32+
// Client is an HTTP client for the Feature Flag Gateway
33+
// endpoint.
34+
type Client struct {
35+
baseURL *url.URL
36+
client *http.Client
37+
}
38+
39+
// NewService creates a new Feature Flag Gateway client.
40+
func NewService(baseURL *url.URL, requestTimeout time.Duration) (*Client, error) {
41+
if baseURL == nil {
42+
return nil, fmt.Errorf("base URL is nil")
43+
}
44+
45+
client := &http.Client{
46+
Timeout: requestTimeout,
47+
}
48+
49+
return &Client{
50+
baseURL: baseURL,
51+
client: client,
52+
}, nil
53+
}
54+
55+
// EvaluateFlags evaluates feature flags for a given organization.
56+
func (c *Client) EvaluateFlags(ctx context.Context, flags []string, orgID string, version string, token string) (featureFlagsResponse *FeatureFlagsResponse, retErr error) {
57+
orgID = strings.TrimSpace(orgID)
58+
if orgID == "" {
59+
return nil, fmt.Errorf("orgID is required")
60+
}
61+
62+
token = strings.TrimSpace(token)
63+
if token == "" {
64+
return nil, fmt.Errorf("token is required")
65+
}
66+
67+
if version == "" {
68+
version = defaultVersion
69+
}
70+
71+
reqBody := buildRequest(flags)
72+
bodyBytes, err := json.Marshal(reqBody)
73+
if err != nil {
74+
return featureFlagsResponse, fmt.Errorf("marshal evaluate flags request: %w", err)
75+
}
76+
77+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.getBaseURL(orgID, version), bytes.NewReader(bodyBytes))
78+
if err != nil {
79+
return featureFlagsResponse, fmt.Errorf("create evaluate flagsrequest: %w", err)
80+
}
81+
82+
req.Header.Add(contentType, ApplicationJSON)
83+
req.Header.Add(accept, ApplicationJSON)
84+
req.Header.Add(userAgent, snykCli)
85+
req.Header.Set(authorization, "token "+token)
86+
87+
resp, err := c.client.Do(req)
88+
if err != nil {
89+
return nil, fmt.Errorf("making evaluate flags request: %w", err)
90+
}
91+
defer func() {
92+
retErr = errors.Join(retErr, resp.Body.Close())
93+
}()
94+
95+
if resp.StatusCode != http.StatusOK {
96+
err = fmt.Errorf("evaluate flags failed: status=%d", resp.StatusCode)
97+
return nil, err
98+
}
99+
100+
if err := json.NewDecoder(resp.Body).Decode(&featureFlagsResponse); err != nil {
101+
return nil, fmt.Errorf("decode evaluate flags response: %w", err)
102+
}
103+
104+
return featureFlagsResponse, nil
105+
}
106+
107+
func buildRequest(flags []string) FeatureFlagRequest {
108+
return FeatureFlagRequest{
109+
Data: FeatureFlagsData{
110+
Type: "feature_flags_evaluation",
111+
Attributes: FeatureFlagsRequestAttributes{
112+
Flags: flags,
113+
},
114+
},
115+
}
116+
}
117+
118+
func (c *Client) getBaseURL(orgID, version string) string {
119+
if version == "" {
120+
version = defaultVersion
121+
}
122+
123+
u := *c.baseURL
124+
u.Path = path.Join(
125+
u.Path,
126+
"orgs",
127+
url.PathEscape(orgID),
128+
"feature_flags",
129+
"evaluation",
130+
)
131+
132+
q := u.Query()
133+
q.Set("version", version)
134+
u.RawQuery = q.Encode()
135+
136+
return u.String()
137+
}

0 commit comments

Comments
 (0)