Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 0825358

Browse files
authored
feat/enterpriseportal: add instance category (#64253)
Per some feedback around https://docs.google.com/document/d/1NyBIQvZ-ziNhiz7Yuzbp4f72Gp6EUrVUoBYnnnviXi8/edit, this adds a "instance type" enumeration for each subscription: 1. PRIMARY: production 2. SECONDARY: dev/testing/staging/whatever 3. INTERNAL: for us ## Test plan Updated tests
1 parent e2c646a commit 0825358

File tree

8 files changed

+753
-514
lines changed

8 files changed

+753
-514
lines changed

cmd/enterprise-portal/internal/database/subscriptions/subscriptions.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ type Subscription struct {
4141
//
4242
// It must be unique across all currently un-archived subscriptions.
4343
InstanceDomain *string `gorm:"uniqueIndex:,where:archived_at IS NULL"`
44-
45-
// WARNING: The below fields are not yet used in production.
44+
// InstanceType is the category of the instance associated with this
45+
// subscription, e.g. 'TYPE_PRIMARY' or 'TYPE_SECONDARY'.
46+
InstanceType *string
4647

4748
// DisplayName is the human-friendly name of this subscription, e.g. "Acme, Inc."
4849
//
@@ -72,6 +73,7 @@ func subscriptionTableColumns() []string {
7273
return []string{
7374
"id",
7475
"instance_domain",
76+
"instance_type",
7577
"display_name",
7678
"created_at",
7779
"updated_at",
@@ -88,6 +90,7 @@ func scanSubscription(row pgx.Row) (*SubscriptionWithConditions, error) {
8890
err := row.Scan(
8991
&s.ID,
9092
&s.InstanceDomain,
93+
&s.InstanceType,
9194
&s.DisplayName,
9295
&s.CreatedAt,
9396
&s.UpdatedAt,
@@ -223,6 +226,8 @@ type UpsertSubscriptionOptions struct {
223226

224227
SalesforceSubscriptionID *sql.NullString
225228

229+
InstanceType *sql.NullString
230+
226231
// ForceUpdate indicates whether to force update all fields of the subscription
227232
// record.
228233
ForceUpdate bool
@@ -233,7 +238,10 @@ type UpsertSubscriptionOptions struct {
233238
func (opts UpsertSubscriptionOptions) apply(ctx context.Context, db upsert.Execer, id string) error {
234239
b := upsert.New("enterprise_portal_subscriptions", "id", opts.ForceUpdate)
235240
upsert.Field(b, "id", id)
241+
236242
upsert.Field(b, "instance_domain", opts.InstanceDomain)
243+
upsert.Field(b, "instance_type", opts.InstanceType)
244+
237245
upsert.Field(b, "display_name", opts.DisplayName)
238246

239247
upsert.Field(b, "created_at", opts.CreatedAt,
@@ -246,6 +254,7 @@ func (opts UpsertSubscriptionOptions) apply(ctx context.Context, db upsert.Exece
246254
upsert.WithIgnoreZeroOnForceUpdate())
247255

248256
upsert.Field(b, "salesforce_subscription_id", opts.SalesforceSubscriptionID)
257+
249258
return b.Exec(ctx, db)
250259
}
251260

cmd/enterprise-portal/internal/database/subscriptions/subscriptions_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ func SubscriptionsStoreGet(t *testing.T, ctx context.Context, s *subscriptions.S
351351
uuid.New().String(),
352352
subscriptions.UpsertSubscriptionOptions{
353353
InstanceDomain: database.NewNullString("s1.sourcegraph.com"),
354+
InstanceType: database.NewNullString(
355+
subscriptionsv1.EnterpriseSubscriptionInstanceType_ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_PRIMARY.String(),
356+
),
354357
},
355358
)
356359
require.NoError(t, err)
@@ -364,6 +367,11 @@ func SubscriptionsStoreGet(t *testing.T, ctx context.Context, s *subscriptions.S
364367
got, err := s.Get(ctx, s1.ID)
365368
require.NoError(t, err)
366369
assert.Equal(t, s1.ID, got.ID)
370+
371+
assert.NotEmpty(t, got.InstanceDomain)
367372
assert.Equal(t, s1.InstanceDomain, got.InstanceDomain)
373+
374+
assert.NotEmpty(t, got.InstanceType)
375+
assert.Equal(t, s1.InstanceType, got.InstanceType)
368376
})
369377
}

cmd/enterprise-portal/internal/subscriptionsservice/adapters.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,18 @@ func convertSubscriptionToProto(subscription *subscriptions.SubscriptionWithCond
8383
}
8484
}
8585

86+
var instanceType subscriptionsv1.EnterpriseSubscriptionInstanceType
87+
if subscription.InstanceType != nil {
88+
instanceType = subscriptionsv1.EnterpriseSubscriptionInstanceType(
89+
subscriptionsv1.EnterpriseSubscriptionInstanceType_value[*subscription.InstanceType],
90+
)
91+
}
92+
8693
return &subscriptionsv1.EnterpriseSubscription{
8794
Id: subscriptionsv1.EnterpriseSubscriptionIDPrefix + subscription.ID,
8895
Conditions: conds,
8996
InstanceDomain: pointers.DerefZero(subscription.InstanceDomain),
97+
InstanceType: instanceType,
9098
DisplayName: pointers.DerefZero(subscription.DisplayName),
9199
Salesforce: sf,
92100
}

cmd/enterprise-portal/internal/subscriptionsservice/adapters_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,32 @@ func TestConvertSubscriptionToProto(t *testing.T) {
145145
"salesforce": {
146146
"subscriptionId": "sf_sub_id"
147147
}
148+
}`),
149+
}, {
150+
name: "with instance category",
151+
sub: &subscriptions.SubscriptionWithConditions{
152+
Subscription: subscriptions.Subscription{
153+
ID: "subscription_id",
154+
InstanceDomain: pointers.Ptr("sourcegraph.com"),
155+
InstanceType: pointers.Ptr(
156+
subscriptionsv1.EnterpriseSubscriptionInstanceType_ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL.String()),
157+
CreatedAt: utctime.Time(created),
158+
},
159+
Conditions: []subscriptions.SubscriptionCondition{{
160+
TransitionTime: utctime.Time(created),
161+
Status: "STATUS_CREATED",
162+
}},
163+
},
164+
want: autogold.Expect(`{
165+
"conditions": [
166+
{
167+
"lastTransitionTime": "2024-01-01T01:01:00Z",
168+
"status": "STATUS_CREATED"
169+
}
170+
],
171+
"id": "es_subscription_id",
172+
"instanceDomain": "sourcegraph.com",
173+
"instanceType": "ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL"
148174
}`),
149175
}} {
150176
t.Run(tc.name, func(t *testing.T) {

cmd/enterprise-portal/internal/subscriptionsservice/v1.go

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

33
import (
44
"context"
5+
"database/sql"
56
"fmt"
67
"net/http"
78
"strings"
@@ -426,6 +427,13 @@ func (s *handlerV1) CreateEnterpriseSubscription(ctx context.Context, req *conne
426427
if strings.TrimSpace(sub.GetDisplayName()) == "" {
427428
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("display_name is required"))
428429
}
430+
if sub.GetInstanceType() == 0 {
431+
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("instance_type is required"))
432+
}
433+
if _, ok := subscriptionsv1.EnterpriseSubscriptionInstanceType_name[int32(sub.GetInstanceType())]; !ok {
434+
return nil, connect.NewError(connect.CodeInvalidArgument,
435+
errors.Newf("invalid 'instance_type' %s", sub.GetInstanceType().String()))
436+
}
429437

430438
// Generate a new ID for the subscription.
431439
if sub.Id != "" {
@@ -450,6 +458,7 @@ func (s *handlerV1) CreateEnterpriseSubscription(ctx context.Context, req *conne
450458
CreatedAt: createdAt,
451459
DisplayName: database.NewNullString(sub.GetDisplayName()),
452460
InstanceDomain: database.NewNullString(sub.GetInstanceDomain()),
461+
InstanceType: database.NewNullString(sub.GetInstanceType().String()),
453462
SalesforceSubscriptionID: database.NewNullString(sub.GetSalesforce().GetSubscriptionId()),
454463
},
455464
subscriptions.CreateSubscriptionConditionOptions{
@@ -507,6 +516,13 @@ func (s *handlerV1) UpdateEnterpriseSubscription(ctx context.Context, req *conne
507516
if v := req.Msg.GetSubscription().GetInstanceDomain(); v != "" {
508517
opts.InstanceDomain = database.NewNullString(v)
509518
}
519+
if v := req.Msg.GetSubscription().GetInstanceType(); v > 0 {
520+
if _, ok := subscriptionsv1.EnterpriseSubscriptionInstanceType_name[int32(v)]; !ok {
521+
return nil, connect.NewError(connect.CodeInvalidArgument,
522+
errors.Newf("invalid 'instance_type' %s", v.String()))
523+
}
524+
opts.InstanceType = database.NewNullString(v.String())
525+
}
510526
if v := req.Msg.GetSubscription().GetDisplayName(); v != "" {
511527
opts.DisplayName = database.NewNullString(v)
512528
}
@@ -525,6 +541,19 @@ func (s *handlerV1) UpdateEnterpriseSubscription(ctx context.Context, req *conne
525541
opts.InstanceDomain =
526542
database.NewNullString(req.Msg.GetSubscription().GetInstanceDomain())
527543
}
544+
if p == "instance_type" || p == "*" {
545+
valid = true
546+
t := req.Msg.GetSubscription().GetInstanceType()
547+
if _, ok := subscriptionsv1.EnterpriseSubscriptionInstanceType_name[int32(t)]; !ok {
548+
return nil, connect.NewError(connect.CodeInvalidArgument,
549+
errors.Newf("invalid 'instance_type' %s", t.String()))
550+
}
551+
if t == 0 {
552+
opts.InstanceType = &sql.NullString{} // unset if zero
553+
} else {
554+
opts.InstanceType = database.NewNullString(t.String())
555+
}
556+
}
528557
if p == "display_name" || p == "*" {
529558
valid = true
530559
opts.DisplayName =

cmd/enterprise-portal/internal/subscriptionsservice/v1_test.go

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ func TestHandlerV1_CreateEnterpriseSubscription(t *testing.T) {
260260
DisplayName: t.Name(),
261261
},
262262
},
263-
wantError: autogold.Expect("invalid_argument: subscription_id can not be set"),
263+
wantError: autogold.Expect("invalid_argument: instance_type is required"),
264264
},
265265
{
266266
name: "insufficient scopes",
@@ -272,8 +272,9 @@ func TestHandlerV1_CreateEnterpriseSubscription(t *testing.T) {
272272
},
273273
create: &subscriptionsv1.CreateEnterpriseSubscriptionRequest{
274274
Subscription: &subscriptionsv1.EnterpriseSubscription{
275-
Id: "not-allowed",
276-
DisplayName: t.Name(),
275+
Id: "not-allowed",
276+
DisplayName: t.Name(),
277+
InstanceType: subscriptionsv1.EnterpriseSubscriptionInstanceType_ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL,
277278
},
278279
},
279280
wantError: autogold.Expect("permission_denied: insufficient scope"),
@@ -282,7 +283,8 @@ func TestHandlerV1_CreateEnterpriseSubscription(t *testing.T) {
282283
name: "with required params only",
283284
create: &subscriptionsv1.CreateEnterpriseSubscriptionRequest{
284285
Subscription: &subscriptionsv1.EnterpriseSubscription{
285-
DisplayName: t.Name(),
286+
DisplayName: t.Name(),
287+
InstanceType: subscriptionsv1.EnterpriseSubscriptionInstanceType_ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL,
286288
},
287289
},
288290
wantUpsertOpts: autogold.Expect(subscriptions.UpsertSubscriptionOptions{
@@ -299,13 +301,18 @@ func TestHandlerV1_CreateEnterpriseSubscription(t *testing.T) {
299301
1,
300302
0),
301303
SalesforceSubscriptionID: &sql.NullString{},
304+
InstanceType: &sql.NullString{
305+
String: "ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL",
306+
Valid: true,
307+
},
302308
}),
303309
},
304310
{
305311
name: "with message and optional fields",
306312
create: &subscriptionsv1.CreateEnterpriseSubscriptionRequest{
307313
Subscription: &subscriptionsv1.EnterpriseSubscription{
308-
DisplayName: t.Name(),
314+
DisplayName: t.Name(),
315+
InstanceType: subscriptionsv1.EnterpriseSubscriptionInstanceType_ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL,
309316
Salesforce: &subscriptionsv1.EnterpriseSubscriptionSalesforceMetadata{
310317
SubscriptionId: "sf_sub",
311318
},
@@ -329,6 +336,10 @@ func TestHandlerV1_CreateEnterpriseSubscription(t *testing.T) {
329336
String: "sf_sub",
330337
Valid: true,
331338
},
339+
InstanceType: &sql.NullString{
340+
String: "ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL",
341+
Valid: true,
342+
},
332343
}),
333344
},
334345
} {
@@ -423,6 +434,17 @@ func TestHandlerV1_UpdateEnterpriseSubscription(t *testing.T) {
423434
},
424435
wantError: autogold.Expect("not_found: subscription not found"),
425436
},
437+
{
438+
name: "invalid type",
439+
update: &subscriptionsv1.UpdateEnterpriseSubscriptionRequest{
440+
Subscription: &subscriptionsv1.EnterpriseSubscription{
441+
Id: mockSubscriptionID,
442+
InstanceType: subscriptionsv1.EnterpriseSubscriptionInstanceType(999),
443+
},
444+
UpdateMask: nil,
445+
},
446+
wantError: autogold.Expect("invalid_argument: invalid 'instance_type' 999"),
447+
},
426448
{
427449
name: "no update mask",
428450
update: &subscriptionsv1.UpdateEnterpriseSubscriptionRequest{
@@ -474,6 +496,35 @@ func TestHandlerV1_UpdateEnterpriseSubscription(t *testing.T) {
474496
Valid: true,
475497
}}),
476498
},
499+
{
500+
name: "specified field mask with instance category enum",
501+
update: &subscriptionsv1.UpdateEnterpriseSubscriptionRequest{
502+
Subscription: &subscriptionsv1.EnterpriseSubscription{
503+
Id: mockSubscriptionID,
504+
InstanceType: subscriptionsv1.EnterpriseSubscriptionInstanceType_ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL,
505+
// Should not be included, as only instance_type is in
506+
// the field mask.
507+
DisplayName: "My Test Subscription",
508+
},
509+
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"instance_type"}},
510+
},
511+
wantUpdateOpts: autogold.Expect(subscriptions.UpsertSubscriptionOptions{InstanceType: &sql.NullString{
512+
String: "ENTERPRISE_SUBSCRIPTION_INSTANCE_TYPE_INTERNAL",
513+
Valid: true,
514+
}}),
515+
},
516+
{
517+
name: "use update_mask to unset instance_type ",
518+
update: &subscriptionsv1.UpdateEnterpriseSubscriptionRequest{
519+
Subscription: &subscriptionsv1.EnterpriseSubscription{
520+
Id: mockSubscriptionID,
521+
// zero-value instance_type
522+
},
523+
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"instance_type"}},
524+
},
525+
// All update-able values should be set to their defaults explicitly
526+
wantUpdateOpts: autogold.Expect(subscriptions.UpsertSubscriptionOptions{InstanceType: &sql.NullString{}}),
527+
},
477528
{
478529
name: "* update_mask",
479530
update: &subscriptionsv1.UpdateEnterpriseSubscriptionRequest{
@@ -488,6 +539,7 @@ func TestHandlerV1_UpdateEnterpriseSubscription(t *testing.T) {
488539
InstanceDomain: &sql.NullString{},
489540
DisplayName: &sql.NullString{},
490541
SalesforceSubscriptionID: &sql.NullString{},
542+
InstanceType: &sql.NullString{},
491543
ForceUpdate: true,
492544
}),
493545
},

0 commit comments

Comments
 (0)