Skip to content

Commit 1164183

Browse files
bietkulsiddharthlatestlakhansamaniharsh-2711bsrk
committed
chore: Unit test for billing + Refactor (#62)
* feat: support es version > 7.0 * feat: add logs * feat: update es version * feat(build): reduce docker image size * fix: PATCH user and permissions endpoint * fix: size issue in logs * feat: add billing * Update main.go * fix: Use tier_validity from accapi * fix: resolve comments * fix: update validity check condition * fix: request logs at index level * fix: billing env & remove email * update accapi * fix: remove subscription id * fix: minor fixes * add logs * fix: minor fixes * fix: update request * fix: remove subscription id * fix: update URL * fix: remove fmt.Println(..) log * fix: minor fixes * fix: minor fixes * fix: update URL * fix: update arc instance endpoint * fix: update URL * feat: allow self signed certs * fix: handle invalid ARC_ID + minor fixes * fix: Rename variable * Refactor: Enhancements + fixes to the billing mechanism (#24) * test: use local ACC_API URL for test * wip: add debug log * wip: add debug log * wip: add debug log * wip: handle case where time validity = 0 * wip: fix time_validity value while a user is in trial * fix: export ArcInstanceDetails and NodeCount - make sure nodes are counted at init time irrespective of a valid subscription_id and report usage call * fix: set type of NodeCount to int * format: remove debug statements * fix: handle case of an invalid ARC_ID * format: improve error message for env not found * fix: Modified query path for Patch Permission test * feat: expose billing variable from util.go (#26) * Add support for custom jwt usename key The usename could be both for users & permissions * Fix indentation * feat: sync to dev * Add support for modifying/deleting role in permission using PATCH request Also add GET handler for getting a permission using role * Fix indentation * feat: allow self signed certs * fix: es7 changes * fixed middleware test of plugin * fix: permission + post user * fix: permission + post user (#29) * RBAC: Add routes to GET/SET public key (#27) * Create CRUD permission handlers for roles * feat: add routes to GET/SET public key * fix: minor fixes * Fix: get public key route if es index is not present (#30) * fix: permission + post user * fix: get public key route if es index is not present * Fixed getCredentialsTest of dao * Fixed minor bug * Fixed putPermissionTest of dao * Fixed jwt token tests * Minor change * Made tests for handlers and completed methods for middleware * Minor changes * feat: support custom headers (#34) * feat: add report usage for hosted cluster (#33) * wip: add flag for hosted billing * feat: add cron for reporting arc cluster usage * fix: remove encryption * Modified tests * fix: allow sources check to pass if all is set * handles IPv6 match case * fix(permission): update referers error message * feat: validate plan * feat: add suggestions category * feat: add limits for missing categories * fix: plan validation for hosted billing * fix: change the plan validation logic * fix: auth header redirection * feat: fetch & set cluster plan * fix: minor fixes * feat: improve validat * fix: minor category fix * fix: minor fixes * fix: suggestions category * fix: minor fixes * fix: update URL * add build flags * fix: minor fixes * feat: apply billing middleware for cluster plans * fix: revert ACC_API url * fix: stop execution if arc instance is not present * fix(billing): hosted arc (#41) * fix: arc_hosted billing * fix: serious billing issue with time_validity * feat: add ingnoreBillingMiddleware flag * fix: revert acc_api * fix: minor fixes * fix: minor changes * fix: docker file (#42) change CMD -> ENTRYPOINT add shared-docker volume path creation * chore: adds default CMD, ignore config files * fix: fallback to highest plan when billing is disabled * fix: minor fixes * mock: proxy getRawLogs() to work with ES v6 and ES v7 * wip: move es client instantiation to a separate file * chore: update to use the new endpoint route * test * fix: use consistent report_usage URI * fix: update report_usage route * fix: time_validity in self-hosted billing * fix: test * fix: blacklist subscription route * fix: blacklist plan route * fix: revert ACC_API * fix(auth): authentication bug with JWT * fix a bug where role name should be queried against .keyword field * fix bug where JWT key from environment variables would override values set in DB * fix a crash where the role key isn't present in JWT claims * format error messages related to username/role authentication for better comprehension * chore: transform POST search request to GET requests (#43) * fix: remove CMD preset * fix: test accapi * fix: remove use of arc_id * fix: revert accapi * fix: set retrier max limit to 8 sec (from 8 ms) * hotfix: add retry logic to ES proxy * feat: use retrable (#46) * feat: add support for source_filtering * feat: apply source filtering for msearch * feat: support es6 in logs plugin * feat: add support for es6 in auth plugin * refactor: parity changes * chore: change the func name * feat: add support for es6 in permissions plugin * feat: add support for es6 in reindexer plugin * feat: add es6 support for users plugin * chore: refactor auth plugin * chore: refactor logs * chore: refactor permissions * fix: warnings * fix: test cases * chore: update to go1.13 * chore: remove test cases + initialize e2e test * fix: GET permissions for es6 * fix: es6 issues in users and permissions * chore: add test cases for permissions * chore: add users plugins test * fix: minor fixes * fix: add authentication to public key routes * fix: minor fixes * feat: public test for RBAC * fix: users test * chore: billing refactor + add unit test cases * chore: add build flags to test tier * fix: minor fixes * refactor: provide response from util method * feat: common util to build arc * fix: minor fixes * Update main.go Co-authored-by: Siddharth Kothari <sids.aquarius@gmail.com> Co-authored-by: Lakhan Samani <lakhan.m.samani@gmail.com> Co-authored-by: Harsh Patel <harshaudi27@gmail.com> Co-authored-by: BSRK Aditya <bsrk@sixb.in> Co-authored-by: Abhinav Raj <abhinav.23.april@gmail.com> Co-authored-by: Jeet Parekh <12874561+jeet-parekh@users.noreply.github.com>
1 parent 9a74872 commit 1164183

10 files changed

Lines changed: 253 additions & 55 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ PLUGIN_MAIN_LOC_FUNC=plugins/$(1)/main/$(1).$(2)
99
PLUGIN_LOC_FUNC=$(foreach PLUGIN,$(PLUGINS),$(call PLUGIN_MAIN_LOC_FUNC,$(PLUGIN),$(1)))
1010

1111
cmd: plugins
12-
$(GC) -ldflags "-w -X main.Billing=$(BILLING) -X main.HostedBilling=$(HOSTED_BILLING) -X main.ClusterBilling=$(CLUSTER_BILLING) -X main.PlanRefreshInterval=$(PLAN_REFRESH_INTERVAL) -X main.IgnoreBillingMiddleware=$(IGNORE_BILLING_MIDDLEWARE)" -o $(BUILD_DIR)/arc main.go
12+
$(GC) -ldflags "-w -X main.Billing=$(BILLING) -X main.HostedBilling=$(HOSTED_BILLING) -X main.ClusterBilling=$(CLUSTER_BILLING) -X main.PlanRefreshInterval=$(PLAN_REFRESH_INTERVAL) -X main.IgnoreBillingMiddleware=$(IGNORE_BILLING_MIDDLEWARE) -X main.Tier=$(TEST_TIER) -X main.FeatureCustomEvents=$(TEST_FEATURE_CUSTOM_EVENTS) -X main.FeatureSuggestions=$(TEST_FEATURE_SUGGESTIONS)" -o $(BUILD_DIR)/arc main.go
1313

1414
plugins: $(call PLUGIN_LOC_FUNC,so)
1515

main.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"bufio"
5+
"encoding/json"
56
"flag"
67
"fmt"
78
"io"
@@ -45,6 +46,13 @@ var (
4546
ClusterBilling string
4647
// IgnoreBillingMiddleware ignores the billing middleware
4748
IgnoreBillingMiddleware string
49+
50+
// Tier for testing
51+
Tier string
52+
// FeatureCustomEvents for testing
53+
FeatureCustomEvents string
54+
// FeatureSuggestions for testing
55+
FeatureSuggestions string
4856
)
4957

5058
func init() {
@@ -128,11 +136,36 @@ func main() {
128136
router.Use(util.BillingMiddleware)
129137
}
130138
} else {
131-
var plan = util.ArcEnterprise
132-
util.Tier = &plan
139+
util.SetDefaultTier()
133140
log.Println("You're running Arc with billing module disabled.")
134141
}
135142

143+
// Testing Env: Set variables based on the build blags
144+
if Tier != "" {
145+
var temp1 = map[string]interface{}{
146+
"tier": Tier,
147+
}
148+
type Temp struct {
149+
Tier *util.Plan `json:"tier"`
150+
}
151+
temp2 := Temp{}
152+
mashalled, err := json.Marshal(temp1)
153+
if err != nil {
154+
log.Fatal(err)
155+
}
156+
err = json.Unmarshal(mashalled, &temp2)
157+
if err != nil {
158+
log.Fatal(err)
159+
}
160+
util.SetTier(temp2.Tier)
161+
}
162+
if FeatureCustomEvents != "" && FeatureCustomEvents == "true" {
163+
util.SetFeatureCustomEvents(true)
164+
}
165+
if FeatureSuggestions != "" && FeatureSuggestions == "true" {
166+
util.SetFeatureSuggestions(true)
167+
}
168+
136169
// ES client instantiation
137170
// ES v7 and v6 clients
138171
util.NewClient()

middleware/validate/plan.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ func Plan(validPlans []util.Plan, byPassValidation bool) middleware.Middleware {
2020
func invalidPlan(h http.HandlerFunc) http.HandlerFunc {
2121
return func(w http.ResponseWriter, req *http.Request) {
2222
msg := "This feature is not available for the free plan users, please upgrade to a paid plan."
23-
if util.Tier != nil {
24-
msg = "This feature is not available for the " + util.Tier.String() + " plan users, please upgrade to a higher plan."
23+
if util.GetTier() != nil {
24+
msg = "This feature is not available for the " + util.GetTier().String() + " plan users, please upgrade to a higher plan."
2525
}
2626
util.WriteBackError(w, msg, http.StatusPaymentRequired)
2727
}

plugins/auth/e2e_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func TestRBAC(t *testing.T) {
177177
var createdAt string
178178
Convey("Testing RBAC", t, func() {
179179
Convey("Save the public key", func() {
180-
response, err := util.MakeHttpRequest(http.MethodPut, "/_public_key", savePublicKeyRequest)
180+
response, err, _ := util.MakeHttpRequest(http.MethodPut, "/_public_key", savePublicKeyRequest)
181181

182182
if err != nil {
183183
t.Fatalf("savePublicKeyTest Failed %v instead\n", err)
@@ -187,7 +187,7 @@ func TestRBAC(t *testing.T) {
187187
})
188188

189189
Convey("Get the public key", func() {
190-
response, err := util.MakeHttpRequest(http.MethodGet, "/_public_key", nil)
190+
response, err, _ := util.MakeHttpRequest(http.MethodGet, "/_public_key", nil)
191191

192192
if err != nil {
193193
t.Fatalf("getPublicKeyTest Failed %v instead\n", err)
@@ -200,7 +200,7 @@ func TestRBAC(t *testing.T) {
200200
requestBody := permission.Permission{
201201
Description: "TEST PERMISSION WITH ROLE",
202202
}
203-
response, err := util.MakeHttpRequest(http.MethodPost, "/_role/"+roleName, requestBody)
203+
response, err, _ := util.MakeHttpRequest(http.MethodPost, "/_role/"+roleName, requestBody)
204204

205205
parsedResponse, _ := response.(map[string]interface{})
206206

@@ -221,7 +221,7 @@ func TestRBAC(t *testing.T) {
221221
})
222222

223223
Convey("Get permission with role", func() {
224-
response, err := util.MakeHttpRequest(http.MethodGet, "/_role/"+roleName, nil)
224+
response, err, _ := util.MakeHttpRequest(http.MethodGet, "/_role/"+roleName, nil)
225225

226226
if err != nil {
227227
t.Fatalf("getPermissionWithRoleTest Failed %v instead\n", err)
@@ -236,7 +236,7 @@ func TestRBAC(t *testing.T) {
236236
})
237237

238238
Convey("Update permission with role", func() {
239-
response, err := util.MakeHttpRequest(http.MethodPatch, "/_role/"+roleName, updatePermissionsRequest)
239+
response, err, _ := util.MakeHttpRequest(http.MethodPatch, "/_role/"+roleName, updatePermissionsRequest)
240240

241241
if err != nil {
242242
t.Fatalf("updatePermissionWithRoleTest Failed %v instead\n", err)
@@ -266,7 +266,7 @@ func TestRBAC(t *testing.T) {
266266
})
267267

268268
Convey("Delete permission with role", func() {
269-
response, err := util.MakeHttpRequest(http.MethodDelete, "/_role/"+roleName, nil)
269+
response, err, _ := util.MakeHttpRequest(http.MethodDelete, "/_role/"+roleName, nil)
270270

271271
if err != nil {
272272
t.Fatalf("deletePermissionWithRoleTest Failed %v instead\n", err)

plugins/permissions/e2e_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func TestPermission(t *testing.T) {
176176
requestBody := permission.Permission{
177177
Description: "TEST PERMISSION",
178178
}
179-
response, err := util.MakeHttpRequest(http.MethodPost, "/_permission", requestBody)
179+
response, err, _ := util.MakeHttpRequest(http.MethodPost, "/_permission", requestBody)
180180

181181
parsedResponse, _ := response.(map[string]interface{})
182182

@@ -197,7 +197,7 @@ func TestPermission(t *testing.T) {
197197
})
198198

199199
Convey("Get permission", func() {
200-
response, err := util.MakeHttpRequest(http.MethodGet, "/_permission/"+username, nil)
200+
response, err, _ := util.MakeHttpRequest(http.MethodGet, "/_permission/"+username, nil)
201201

202202
if err != nil {
203203
t.Fatalf("getPermissionTest Failed %v instead\n", err)
@@ -212,7 +212,7 @@ func TestPermission(t *testing.T) {
212212
})
213213

214214
Convey("Get permissions", func() {
215-
response, err := util.MakeHttpRequest(http.MethodGet, "/_permissions", nil)
215+
response, err, _ := util.MakeHttpRequest(http.MethodGet, "/_permissions", nil)
216216

217217
if err != nil {
218218
t.Fatalf("getPermissionsTest Failed %v instead\n", err)
@@ -229,7 +229,7 @@ func TestPermission(t *testing.T) {
229229
})
230230

231231
Convey("Update permission", func() {
232-
response, err := util.MakeHttpRequest(http.MethodPatch, "/_permission/"+username, updatePermissionsRequest)
232+
response, err, _ := util.MakeHttpRequest(http.MethodPatch, "/_permission/"+username, updatePermissionsRequest)
233233

234234
if err != nil {
235235
t.Fatalf("updatePermissionTest Failed %v instead\n", err)
@@ -259,7 +259,7 @@ func TestPermission(t *testing.T) {
259259
})
260260

261261
Convey("Delete permission", func() {
262-
response, err := util.MakeHttpRequest(http.MethodDelete, "/_permission/"+username, nil)
262+
response, err, _ := util.MakeHttpRequest(http.MethodDelete, "/_permission/"+username, nil)
263263

264264
if err != nil {
265265
t.Fatalf("deletePermissionTest Failed %v instead\n", err)

plugins/users/e2e_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func TestUser(t *testing.T) {
126126
username, _ := createUserRequest["username"].(string)
127127
Convey("Testing users", t, func() {
128128
Convey("Create an user", func() {
129-
response, err := util.MakeHttpRequest(http.MethodPost, "/_user", createUserRequest)
129+
response, err, _ := util.MakeHttpRequest(http.MethodPost, "/_user", createUserRequest)
130130

131131
parsedResponse, _ := response.(map[string]interface{})
132132

@@ -143,7 +143,7 @@ func TestUser(t *testing.T) {
143143
})
144144

145145
Convey("Get user", func() {
146-
response, err := util.MakeHttpRequest(http.MethodGet, "/_user/"+username, nil)
146+
response, err, _ := util.MakeHttpRequest(http.MethodGet, "/_user/"+username, nil)
147147

148148
if err != nil {
149149
t.Fatalf("getUserTest Failed %v instead\n", err)
@@ -164,7 +164,7 @@ func TestUser(t *testing.T) {
164164
})
165165

166166
Convey("Get users", func() {
167-
response, err := util.MakeHttpRequest(http.MethodGet, "/_users", nil)
167+
response, err, _ := util.MakeHttpRequest(http.MethodGet, "/_users", nil)
168168

169169
if err != nil {
170170
t.Fatalf("getUsersTest Failed %v instead\n", err)
@@ -188,7 +188,7 @@ func TestUser(t *testing.T) {
188188
})
189189

190190
Convey("Update user", func() {
191-
response, err := util.MakeHttpRequest(http.MethodPatch, "/_user/"+username, updateUserRequest)
191+
response, err, _ := util.MakeHttpRequest(http.MethodPatch, "/_user/"+username, updateUserRequest)
192192

193193
if err != nil {
194194
t.Fatalf("updateUserTest Failed %v instead\n", err)
@@ -218,7 +218,7 @@ func TestUser(t *testing.T) {
218218
})
219219

220220
Convey("Delete user", func() {
221-
response, err := util.MakeHttpRequest(http.MethodDelete, "/_user/"+username, nil)
221+
response, err, _ := util.MakeHttpRequest(http.MethodDelete, "/_user/"+username, nil)
222222

223223
if err != nil {
224224
t.Fatalf("deleteUserTest Failed %v instead\n", err)

util/billing.go

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,60 @@ var ACCAPI = "https://accapi.appbase.io/"
1717

1818
// var ACCAPI = "http://localhost:3000/"
1919

20-
// TimeValidity to be obtained from ACCAPI
21-
var TimeValidity int64
22-
2320
// Tier is the value of the user's plan
24-
var Tier *Plan
21+
var tier *Plan
22+
23+
// SetTier sets the tier value
24+
func SetTier(plan *Plan) {
25+
tier = plan
26+
}
27+
28+
// GetTier returns the current tier
29+
func GetTier() *Plan {
30+
return tier
31+
}
32+
33+
// TimeValidity to be obtained from ACCAPI (in secs)
34+
var timeValidity int64
35+
36+
// GetTimeValidity returns the time validity
37+
func GetTimeValidity() int64 {
38+
return timeValidity
39+
}
40+
41+
// SetTimeValidity returns the time validity
42+
func SetTimeValidity(time int64) {
43+
timeValidity = time
44+
}
2545

2646
// Feature custom events
27-
var FeatureCustomEvents bool
47+
var featureCustomEvents bool
48+
49+
// GetFeatureCustomEvents returns the featureCustomEvents
50+
func GetFeatureCustomEvents() bool {
51+
return featureCustomEvents
52+
}
53+
54+
// SetFeatureCustomEvents returns the time validity
55+
func SetFeatureCustomEvents(val bool) {
56+
featureCustomEvents = val
57+
}
2858

2959
// Feature suggestions
30-
var FeatureSuggestions bool
60+
var featureSuggestions bool
61+
62+
// GetFeatureSuggestions returns the featureSuggestions
63+
func GetFeatureSuggestions() bool {
64+
return featureSuggestions
65+
}
66+
67+
// SetFeatureSuggestions returns the time validity
68+
func SetFeatureSuggestions(val bool) {
69+
featureSuggestions = val
70+
}
3171

32-
// MaxErrorTime before showing errors if invalid trial / plan in hours
33-
var MaxErrorTime int64 = 24 // in hrs
72+
// maxErrorTime before showing errors if invalid trial / plan in hours
73+
var maxErrorTime int64 = 24 // in hrs
3474

3575
// NodeCount is the current node count, defaults to 1
3676
var NodeCount = 1
@@ -96,18 +136,31 @@ type ArcInstanceDetails struct {
96136
FeatureSuggestions bool `json:"feature_suggestions"`
97137
}
98138

139+
// SetDefaultTier sets the default tier when billing is disabled
140+
func SetDefaultTier() {
141+
var plan = ArcEnterprise
142+
SetTier(&plan)
143+
}
144+
145+
func validateTimeValidity() bool {
146+
if GetTimeValidity() > 0 { // Valid plan
147+
return true
148+
} else if GetTimeValidity() <= 0 && -GetTimeValidity() < 3600*maxErrorTime { // Negative validity, plan has been expired
149+
// Print warning message if remaining time is less than max allowed time
150+
log.Println("Warning: Payment is required. Arc will start sending out error messages in next", maxErrorTime, "hours")
151+
return true
152+
}
153+
return false
154+
}
155+
99156
// BillingMiddleware function to be called for each request
100157
func BillingMiddleware(next http.Handler) http.Handler {
101158
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
102-
log.Println("current time validity value: ", TimeValidity)
159+
log.Println("current time validity value: ", GetTimeValidity())
103160
// Blacklist subscription routes
104161
if strings.HasPrefix(r.RequestURI, "/arc/subscription") || strings.HasPrefix(r.RequestURI, "/arc/plan") {
105162
next.ServeHTTP(w, r)
106-
} else if TimeValidity > 0 { // Valid plan
107-
next.ServeHTTP(w, r)
108-
} else if TimeValidity <= 0 && -TimeValidity < 3600*MaxErrorTime { // Negative validity, plan has been expired
109-
// Print warning message if remaining time is less than max allowed time
110-
log.Println("Warning: Payment is required. Arc will start sending out error messages in next", MaxErrorTime, "hours")
163+
} else if validateTimeValidity() {
111164
next.ServeHTTP(w, r)
112165
} else {
113166
// Write an error and stop the handler chain
@@ -139,10 +192,10 @@ func getArcInstance(arcID string) (ArcInstance, error) {
139192
if len(response.ArcInstances) != 0 {
140193
arcInstanceByID := response.ArcInstances[0]
141194
arcInstance.SubscriptionID = arcInstanceByID.SubscriptionID
142-
TimeValidity = arcInstanceByID.TimeValidity
143-
Tier = arcInstanceByID.Tier
144-
FeatureCustomEvents = arcInstanceByID.FeatureCustomEvents
145-
FeatureSuggestions = arcInstanceByID.FeatureSuggestions
195+
SetTimeValidity(arcInstanceByID.TimeValidity)
196+
SetTier(arcInstanceByID.Tier)
197+
SetFeatureSuggestions(arcInstanceByID.FeatureSuggestions)
198+
SetFeatureCustomEvents(arcInstanceByID.FeatureCustomEvents)
146199
} else {
147200
return arcInstance, errors.New("No valid instance found for the provided ARC_ID")
148201
}
@@ -182,10 +235,10 @@ func getArcClusterInstance(clusterID string) (ArcInstance, error) {
182235
if len(response.ArcInstances) != 0 {
183236
arcInstanceDetails := response.ArcInstances[0]
184237
arcInstance.SubscriptionID = arcInstanceDetails.SubscriptionID
185-
TimeValidity = arcInstanceDetails.TimeValidity
186-
Tier = arcInstanceDetails.Tier
187-
FeatureCustomEvents = arcInstanceDetails.FeatureCustomEvents
188-
FeatureSuggestions = arcInstanceDetails.FeatureSuggestions
238+
SetTimeValidity(arcInstanceDetails.TimeValidity)
239+
SetTier(arcInstanceDetails.Tier)
240+
SetFeatureSuggestions(arcInstanceDetails.FeatureSuggestions)
241+
SetFeatureCustomEvents(arcInstanceDetails.FeatureCustomEvents)
189242
} else {
190243
return arcInstance, errors.New("No valid instance found for the provided CLUSTER_ID")
191244
}
@@ -223,10 +276,10 @@ func getClusterPlan(clusterID string) (ClusterPlan, error) {
223276
return clusterPlan, fmt.Errorf("error while getting the cluster plan")
224277
}
225278
// Set the plan for clusters
226-
Tier = response.Plan.Tier
227-
TimeValidity = response.Plan.TimeValidity
228-
FeatureCustomEvents = response.Plan.FeatureCustomEvents
229-
FeatureSuggestions = response.Plan.FeatureSuggestions
279+
SetTier(response.Plan.Tier)
280+
SetTimeValidity(response.Plan.TimeValidity)
281+
SetFeatureSuggestions(response.Plan.FeatureSuggestions)
282+
SetFeatureCustomEvents(response.Plan.FeatureCustomEvents)
230283

231284
return clusterPlan, nil
232285
}

0 commit comments

Comments
 (0)