From 91ddc5ac266284ad750fc801ed66aa29666f46d3 Mon Sep 17 00:00:00 2001 From: Daniel Agbay Date: Mon, 8 Jan 2024 16:23:52 -0600 Subject: [PATCH 1/2] only query subscriptions service with sku based features --- config/main.go | 10 ---------- controllers/subscriptions.go | 21 +++++++++++++++++++-- controllers/subscriptions_test.go | 7 +++++++ go.mod | 9 +++++---- go.sum | 22 ++++++++++++---------- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/config/main.go b/config/main.go index ae00100..f3c03ed 100644 --- a/config/main.go +++ b/config/main.go @@ -7,7 +7,6 @@ import ( "os" "path/filepath" "runtime" - "strings" "github.com/spf13/viper" @@ -42,7 +41,6 @@ type EntitlementsConfigKeysType struct { CwKey string CwSecret string Features string - FeaturesPath string SubAPIBasePath string CompAPIBasePath string RunBundleSync string @@ -103,11 +101,6 @@ var Keys = EntitlementsConfigKeysType{ AMSAcctMgmt11Msg: "AMS_ACCT_MGMT_11_ERR_MSG", } -func getBaseFeaturesPath(options *viper.Viper) string { - featureList := strings.Split(options.GetString(Keys.Features), ",") - return "?features=" + strings.Join(featureList, "&features=") -} - func getRootCAs(localCertFile string) *x509.CertPool { // force the CA cert rootCAs, err := x509.SystemCertPool() @@ -201,9 +194,6 @@ func initialize() { options.SetEnvPrefix("ENT") options.AutomaticEnv() - // Must be set after AutomaticEnv() in order to pickup FEATURES env variable - options.SetDefault(Keys.FeaturesPath, getBaseFeaturesPath(options)) - config = &EntitlementsConfig{ Certs: getCerts(options), RootCAs: getRootCAs(options.GetString(Keys.CaPath)), diff --git a/controllers/subscriptions.go b/controllers/subscriptions.go index eccb5d3..c339af4 100644 --- a/controllers/subscriptions.go +++ b/controllers/subscriptions.go @@ -21,6 +21,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/sirupsen/logrus" + "golang.org/x/exp/slices" "gopkg.in/yaml.v2" ) @@ -33,6 +34,7 @@ var cache = ccache.New( var cacheDurationSeconds = time.Second * time.Duration(configOptions.GetInt64(config.Keys.SubsCacheDuration)) var bundleInfo []types.Bundle +var subsQueryFeatures string var subsFailure = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "it_subscriptions_service_failure", @@ -81,6 +83,19 @@ func SetBundleInfo(yamlFilePath string) error { return nil } +func setSubscriptionsQueryFeatures() { + features := strings.Split(configOptions.GetString(config.Keys.Features), ",") + + var skuBasedFeatures []string + for _, bundle := range bundleInfo { + if slices.Contains(features, bundle.Name) && bundle.Skus != nil && len(bundle.Skus) > 0 { + skuBasedFeatures = append(skuBasedFeatures, bundle.Name) + } + } + + subsQueryFeatures = "?features=" + strings.Join(skuBasedFeatures, "&features=") +} + // GetFeatureStatus calls the IT subs service features endpoint and returns the entitlements for specified features/bundles var GetFeatureStatus = func(params GetFeatureStatusParams) types.SubscriptionsResponse { orgID := params.OrgId @@ -103,10 +118,12 @@ var GetFeatureStatus = func(params GetFeatureStatusParams) types.SubscriptionsRe } } - q := configOptions.GetString(config.Keys.FeaturesPath) + if subsQueryFeatures == "" { // build the static part of our query only once + setSubscriptionsQueryFeatures() + } req := configOptions.GetString(config.Keys.SubsHost) + "/svcrest/subscription/v5/featureStatus" + - q + "&accountId=" + orgID + subsQueryFeatures + "&accountId=" + orgID resp, err := getClient().Get(req) diff --git a/controllers/subscriptions_test.go b/controllers/subscriptions_test.go index e0cd75a..a1ec613 100644 --- a/controllers/subscriptions_test.go +++ b/controllers/subscriptions_test.go @@ -95,6 +95,13 @@ var _ = Describe("Services Controller", func() { testRequest("GET", "/", DEFAULT_ACCOUNT_NUMBER, "deadbeef12", DEFAULT_IS_INTERNAL, DEFAULT_EMAIL, fakeGetFeatureStatus("deadbeef12", fakeResponse)) }) + It("should build the subscriptions query with only sku based features", func () { + cfg := config.GetConfig() + cfg.Options.Set(config.Keys.Features, "TestBundle1,TestBundle3,TestBundle4,TestBundle5,TestBundle6,TestBundle7") + setSubscriptionsQueryFeatures() + Expect(subsQueryFeatures).To(BeEquivalentTo("?features=TestBundle1&features=TestBundle6")) + }) + Context("When the Subs API sends back a non-200", func() { It("should fail the response", func() { rr, _, rawBody := testRequestWithDefaultOrgId("GET", "/", func(GetFeatureStatusParams) SubscriptionsResponse { diff --git a/go.mod b/go.mod index e75dd65..968cb47 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,8 @@ require ( github.com/redhatinsights/platform-go-middlewares v0.20.1-0.20230119152702-e3779317d1aa github.com/sirupsen/logrus v1.9.0 github.com/spf13/viper v1.15.0 - golang.org/x/text v0.13.0 + golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc + golang.org/x/text v0.14.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -71,9 +72,9 @@ require ( go.uber.org/goleak v1.1.12 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/tools v0.12.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/tools v0.16.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index a64d461..5ccb80d 100644 --- a/go.sum +++ b/go.sum @@ -506,7 +506,7 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -517,6 +517,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -543,7 +545,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -591,8 +593,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -681,8 +683,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -696,8 +698,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -757,8 +759,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From ff10f57bfa3ad8d744d782567624c6cf2fcec271 Mon Sep 17 00:00:00 2001 From: Daniel Agbay Date: Mon, 8 Jan 2024 16:46:21 -0600 Subject: [PATCH 2/2] added request url to logs --- controllers/subscriptions.go | 5 ++++- types/main.go | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/controllers/subscriptions.go b/controllers/subscriptions.go index c339af4..b341e3c 100644 --- a/controllers/subscriptions.go +++ b/controllers/subscriptions.go @@ -131,6 +131,7 @@ var GetFeatureStatus = func(params GetFeatureStatusParams) types.SubscriptionsRe sentry.CaptureException(err) return types.SubscriptionsResponse{ Error: err, + Url: req, } } @@ -143,6 +144,7 @@ var GetFeatureStatus = func(params GetFeatureStatusParams) types.SubscriptionsRe Error: nil, Data: types.FeatureStatus{}, CacheHit: false, + Url: req, } } @@ -159,6 +161,7 @@ var GetFeatureStatus = func(params GetFeatureStatusParams) types.SubscriptionsRe StatusCode: resp.StatusCode, Data: FeatureStatus, CacheHit: false, + Url: req, } } @@ -220,7 +223,7 @@ func Services() func(http.ResponseWriter, *http.Request) { } subsTimeTaken := time.Since(start).Seconds() - l.Log.WithFields(logrus.Fields{"subs_call_duration": subsTimeTaken, "cache_hit": subscriptions.CacheHit}).Info("subs call complete") + l.Log.WithFields(logrus.Fields{"subs_call_duration": subsTimeTaken, "cache_hit": subscriptions.CacheHit, "url": subscriptions.Url}).Info("subs call complete") subsTimeHistogram.Observe(subsTimeTaken) if subscriptions.StatusCode != 200 { diff --git a/types/main.go b/types/main.go index 4350dfc..d45e228 100644 --- a/types/main.go +++ b/types/main.go @@ -14,6 +14,7 @@ type SubscriptionsResponse struct { Error error Data FeatureStatus CacheHit bool + Url string } type Feature struct {