diff --git a/cmd/flipt/export.go b/cmd/flipt/export.go index ce47422041..58373a645f 100644 --- a/cmd/flipt/export.go +++ b/cmd/flipt/export.go @@ -35,6 +35,7 @@ type Variant struct { Key string `yaml:"key,omitempty"` Name string `yaml:"name,omitempty"` Description string `yaml:"description,omitempty"` + Attachment []byte `yaml:"attachment,omitempty"` } type Rule struct { @@ -149,6 +150,7 @@ func runExport(_ []string) error { Key: v.Key, Name: v.Name, Description: v.Description, + Attachment: v.Attachment, }) variantKeys[v.Id] = v.Key diff --git a/cmd/flipt/import.go b/cmd/flipt/import.go index 13e6fb4bf9..dcd2734542 100644 --- a/cmd/flipt/import.go +++ b/cmd/flipt/import.go @@ -139,6 +139,7 @@ func runImport(args []string) error { Key: v.Key, Name: v.Name, Description: v.Description, + Attachment: v.Attachment, }) if err != nil { diff --git a/config/migrations/mysql/1_variants_attachment.down.sql b/config/migrations/mysql/1_variants_attachment.down.sql new file mode 100644 index 0000000000..b4f264a117 --- /dev/null +++ b/config/migrations/mysql/1_variants_attachment.down.sql @@ -0,0 +1 @@ +ALTER TABLE variants DROP COLUMN attachment; diff --git a/config/migrations/mysql/1_variants_attachment.up.sql b/config/migrations/mysql/1_variants_attachment.up.sql new file mode 100644 index 0000000000..b8a14705f2 --- /dev/null +++ b/config/migrations/mysql/1_variants_attachment.up.sql @@ -0,0 +1 @@ +ALTER TABLE variants ADD COLUMN attachment MEDIUMBLOB AFTER description; diff --git a/config/migrations/postgres/3_variants_attachment.down.sql b/config/migrations/postgres/3_variants_attachment.down.sql new file mode 100644 index 0000000000..b4f264a117 --- /dev/null +++ b/config/migrations/postgres/3_variants_attachment.down.sql @@ -0,0 +1 @@ +ALTER TABLE variants DROP COLUMN attachment; diff --git a/config/migrations/postgres/3_variants_attachment.up.sql b/config/migrations/postgres/3_variants_attachment.up.sql new file mode 100644 index 0000000000..5d8b706b84 --- /dev/null +++ b/config/migrations/postgres/3_variants_attachment.up.sql @@ -0,0 +1 @@ +ALTER TABLE variants ADD attachment BYTEA; diff --git a/config/migrations/sqlite3/3_variants_attachment.down.sql b/config/migrations/sqlite3/3_variants_attachment.down.sql new file mode 100644 index 0000000000..b4f264a117 --- /dev/null +++ b/config/migrations/sqlite3/3_variants_attachment.down.sql @@ -0,0 +1 @@ +ALTER TABLE variants DROP COLUMN attachment; diff --git a/config/migrations/sqlite3/3_variants_attachment.up.sql b/config/migrations/sqlite3/3_variants_attachment.up.sql new file mode 100644 index 0000000000..a7c0a6a61c --- /dev/null +++ b/config/migrations/sqlite3/3_variants_attachment.up.sql @@ -0,0 +1 @@ +ALTER TABLE variants ADD COLUMN attachment BLOB AFTER description; diff --git a/rpc/flipt/flipt.pb.go b/rpc/flipt/flipt.pb.go index baac0edace..e8484299cc 100644 --- a/rpc/flipt/flipt.pb.go +++ b/rpc/flipt/flipt.pb.go @@ -875,6 +875,7 @@ type Variant struct { Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Attachment []byte `protobuf:"bytes,8,opt,name=attachment,proto3" json:"attachment,omitempty"` } func (x *Variant) Reset() { @@ -958,6 +959,13 @@ func (x *Variant) GetUpdatedAt() *timestamppb.Timestamp { return nil } +func (x *Variant) GetAttachment() []byte { + if x != nil { + return x.Attachment + } + return nil +} + type CreateVariantRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -967,6 +975,7 @@ type CreateVariantRequest struct { Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + Attachment []byte `protobuf:"bytes,5,opt,name=attachment,proto3" json:"attachment,omitempty"` } func (x *CreateVariantRequest) Reset() { @@ -1029,6 +1038,13 @@ func (x *CreateVariantRequest) GetDescription() string { return "" } +func (x *CreateVariantRequest) GetAttachment() []byte { + if x != nil { + return x.Attachment + } + return nil +} + type UpdateVariantRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1039,6 +1055,7 @@ type UpdateVariantRequest struct { Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` + Attachment []byte `protobuf:"bytes,6,opt,name=attachment,proto3" json:"attachment,omitempty"` } func (x *UpdateVariantRequest) Reset() { @@ -1108,6 +1125,13 @@ func (x *UpdateVariantRequest) GetDescription() string { return "" } +func (x *UpdateVariantRequest) GetAttachment() []byte { + if x != nil { + return x.Attachment + } + return nil +} + type DeleteVariantRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2849,7 +2873,7 @@ var file_flipt_proto_rawDesc = []byte{ 0x6d, 0x65, 0x22, 0x32, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x3a, 0x0b, 0x92, 0x41, 0x08, 0x0a, 0x06, - 0xd2, 0x01, 0x03, 0x6b, 0x65, 0x79, 0x22, 0xf2, 0x01, 0x0a, 0x07, 0x56, 0x61, 0x72, 0x69, 0x61, + 0xd2, 0x01, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x92, 0x02, 0x0a, 0x07, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x6c, 0x61, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, @@ -2864,7 +2888,9 @@ var file_flipt_proto_rawDesc = []byte{ 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x91, 0x01, 0x0a, 0x14, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xb1, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x6c, 0x61, 0x67, 0x4b, 0x65, 0x79, 0x12, @@ -2872,9 +2898,11 @@ var file_flipt_proto_rawDesc = []byte{ 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x16, 0x92, 0x41, 0x13, 0x0a, 0x11, 0xd2, 0x01, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x74, 0x74, + 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x16, 0x92, 0x41, 0x13, 0x0a, 0x11, 0xd2, 0x01, 0x08, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0xd2, 0x01, 0x03, 0x6b, 0x65, 0x79, 0x22, - 0xa6, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, + 0xc6, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x6c, 0x61, 0x67, @@ -2882,7 +2910,9 @@ var file_flipt_proto_rawDesc = []byte{ 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x1b, 0x92, 0x41, 0x18, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x1b, 0x92, 0x41, 0x18, 0x0a, 0x16, 0xd2, 0x01, 0x02, 0x69, 0x64, 0xd2, 0x01, 0x08, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x6b, 0x65, 0x79, 0xd2, 0x01, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x58, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, diff --git a/rpc/flipt/flipt.proto b/rpc/flipt/flipt.proto index ebc2161939..7f9eb27ca5 100644 --- a/rpc/flipt/flipt.proto +++ b/rpc/flipt/flipt.proto @@ -143,6 +143,7 @@ message Variant { string description = 5; google.protobuf.Timestamp created_at = 6; google.protobuf.Timestamp updated_at = 7; + bytes attachment = 8; } message CreateVariantRequest { @@ -156,6 +157,7 @@ message CreateVariantRequest { string key = 2; string name = 3; string description = 4; + bytes attachment = 5; } message UpdateVariantRequest { @@ -170,6 +172,7 @@ message UpdateVariantRequest { string key = 3; string name = 4; string description = 5; + bytes attachment = 6; } message DeleteVariantRequest { diff --git a/rpc/flipt/validation_test.go b/rpc/flipt/validation_test.go index e12ac9d563..bb78354794 100644 --- a/rpc/flipt/validation_test.go +++ b/rpc/flipt/validation_test.go @@ -229,6 +229,7 @@ func TestValidate_CreateVariantRequest(t *testing.T) { Key: "key", Name: "name", Description: "desc", + Attachment: []byte("attachment"), }, wantErr: errors.EmptyFieldError("flagKey"), }, @@ -239,6 +240,7 @@ func TestValidate_CreateVariantRequest(t *testing.T) { Key: "", Name: "name", Description: "desc", + Attachment: []byte("attachment"), }, wantErr: errors.EmptyFieldError("key"), }, @@ -251,6 +253,16 @@ func TestValidate_CreateVariantRequest(t *testing.T) { Description: "desc", }, }, + { + name: "validWithAttachment", + req: &CreateVariantRequest{ + FlagKey: "flagKey", + Key: "key", + Name: "name", + Description: "desc", + Attachment: []byte("attachment"), + }, + }, } for _, tt := range tests { @@ -280,6 +292,7 @@ func TestValidate_UpdateVariantRequest(t *testing.T) { Key: "key", Name: "name", Description: "desc", + Attachment: []byte("attachment"), }, wantErr: errors.EmptyFieldError("id"), }, @@ -291,6 +304,7 @@ func TestValidate_UpdateVariantRequest(t *testing.T) { Key: "key", Name: "name", Description: "desc", + Attachment: []byte("attachment"), }, wantErr: errors.EmptyFieldError("flagKey"), }, @@ -302,6 +316,7 @@ func TestValidate_UpdateVariantRequest(t *testing.T) { Key: "", Name: "name", Description: "desc", + Attachment: []byte("attachment"), }, wantErr: errors.EmptyFieldError("key"), }, @@ -315,6 +330,17 @@ func TestValidate_UpdateVariantRequest(t *testing.T) { Description: "desc", }, }, + { + name: "validWithAttachment", + req: &UpdateVariantRequest{ + Id: "id", + FlagKey: "flagKey", + Key: "key", + Name: "name", + Description: "desc", + Attachment: []byte("attachment"), + }, + }, } for _, tt := range tests { diff --git a/server/flag_test.go b/server/flag_test.go index 8f72817c47..2ff1ade13d 100644 --- a/server/flag_test.go +++ b/server/flag_test.go @@ -140,6 +140,7 @@ func TestCreateVariant(t *testing.T) { Key: "key", Name: "name", Description: "desc", + Attachment: []byte("attachment"), } ) @@ -149,6 +150,7 @@ func TestCreateVariant(t *testing.T) { Key: req.Key, Name: req.Name, Description: req.Description, + Attachment: req.Attachment, }, nil) got, err := s.CreateVariant(context.TODO(), req) @@ -170,6 +172,7 @@ func TestUpdateVariant(t *testing.T) { Key: "key", Name: "name", Description: "desc", + Attachment: []byte("attachment"), } ) @@ -179,6 +182,7 @@ func TestUpdateVariant(t *testing.T) { Key: req.Key, Name: req.Name, Description: req.Description, + Attachment: req.Attachment, }, nil) got, err := s.UpdateVariant(context.TODO(), req) diff --git a/storage/sql/common/flag.go b/storage/sql/common/flag.go index 77ce5c9ee5..fbb28869a2 100644 --- a/storage/sql/common/flag.go +++ b/storage/sql/common/flag.go @@ -187,14 +187,15 @@ func (s *Store) CreateVariant(ctx context.Context, r *flipt.CreateVariantRequest Key: r.Key, Name: r.Name, Description: r.Description, + Attachment: r.Attachment, CreatedAt: now, UpdatedAt: now, } ) if _, err := s.builder.Insert("variants"). - Columns("id", "flag_key", "\"key\"", "name", "description", "created_at", "updated_at"). - Values(v.Id, v.FlagKey, v.Key, v.Name, v.Description, ×tamp{v.CreatedAt}, ×tamp{v.UpdatedAt}). + Columns("id", "flag_key", "\"key\"", "name", "description", "attachment", "created_at", "updated_at"). + Values(v.Id, v.FlagKey, v.Key, v.Name, v.Description, v.Attachment, ×tamp{v.CreatedAt}, ×tamp{v.UpdatedAt}). ExecContext(ctx); err != nil { return nil, err } @@ -208,6 +209,7 @@ func (s *Store) UpdateVariant(ctx context.Context, r *flipt.UpdateVariantRequest Set("\"key\"", r.Key). Set("name", r.Name). Set("description", r.Description). + Set("attachment", r.Attachment). Set("updated_at", ×tamp{timestamppb.Now()}). Where(sq.And{sq.Eq{"id": r.Id}, sq.Eq{"flag_key": r.FlagKey}}) @@ -232,11 +234,11 @@ func (s *Store) UpdateVariant(ctx context.Context, r *flipt.UpdateVariantRequest v = &flipt.Variant{} ) - if err := s.builder.Select("id, \"key\", flag_key, name, description, created_at, updated_at"). + if err := s.builder.Select("id, \"key\", flag_key, name, description, attachment, created_at, updated_at"). From("variants"). Where(sq.And{sq.Eq{"id": r.Id}, sq.Eq{"flag_key": r.FlagKey}}). QueryRowContext(ctx). - Scan(&v.Id, &v.Key, &v.FlagKey, &v.Name, &v.Description, &createdAt, &updatedAt); err != nil { + Scan(&v.Id, &v.Key, &v.FlagKey, &v.Name, &v.Description, &v.Attachment, &createdAt, &updatedAt); err != nil { return nil, err } @@ -256,7 +258,7 @@ func (s *Store) DeleteVariant(ctx context.Context, r *flipt.DeleteVariantRequest } func (s *Store) variants(ctx context.Context, flag *flipt.Flag) (err error) { - query := s.builder.Select("id, flag_key, \"key\", name, description, created_at, updated_at"). + query := s.builder.Select("id, flag_key, \"key\", name, description, attachment, created_at, updated_at"). From("variants"). Where(sq.Eq{"flag_key": flag.Key}). OrderBy("created_at ASC") @@ -284,6 +286,7 @@ func (s *Store) variants(ctx context.Context, flag *flipt.Flag) (err error) { &variant.Key, &variant.Name, &variant.Description, + &variant.Attachment, &createdAt, &updatedAt); err != nil { return err diff --git a/storage/sql/flag_test.go b/storage/sql/flag_test.go index e028cfefe8..b88a6552eb 100644 --- a/storage/sql/flag_test.go +++ b/storage/sql/flag_test.go @@ -215,6 +215,7 @@ func TestCreateVariant(t *testing.T) { Key: t.Name(), Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) require.NoError(t, err) @@ -225,6 +226,7 @@ func TestCreateVariant(t *testing.T) { assert.Equal(t, t.Name(), variant.Key) assert.Equal(t, "foo", variant.Name) assert.Equal(t, "bar", variant.Description) + assert.Equal(t, []byte("baz"), variant.Attachment) assert.NotZero(t, variant.CreatedAt) assert.Equal(t, variant.CreatedAt.Seconds, variant.UpdatedAt.Seconds) @@ -243,6 +245,7 @@ func TestCreateVariant_FlagNotFound(t *testing.T) { Key: t.Name(), Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) assert.EqualError(t, err, "flag \"foo\" not found") @@ -264,6 +267,7 @@ func TestCreateVariant_DuplicateName(t *testing.T) { Key: "foo", Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) require.NoError(t, err) @@ -275,6 +279,7 @@ func TestCreateVariant_DuplicateName(t *testing.T) { Key: "foo", Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) assert.EqualError(t, err, "variant \"foo\" is not unique") @@ -296,6 +301,7 @@ func TestCreateVariant_DuplicateName_DifferentFlag(t *testing.T) { Key: "foo", Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) require.NoError(t, err) @@ -320,6 +326,7 @@ func TestCreateVariant_DuplicateName_DifferentFlag(t *testing.T) { Key: "foo", Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) require.NoError(t, err) @@ -346,6 +353,7 @@ func TestUpdateVariant(t *testing.T) { Key: "foo", Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) require.NoError(t, err) @@ -356,6 +364,7 @@ func TestUpdateVariant(t *testing.T) { assert.Equal(t, "foo", variant.Key) assert.Equal(t, "foo", variant.Name) assert.Equal(t, "bar", variant.Description) + assert.Equal(t, []byte("baz"), variant.Attachment) assert.NotZero(t, variant.CreatedAt) assert.Equal(t, variant.CreatedAt.Seconds, variant.UpdatedAt.Seconds) @@ -365,6 +374,7 @@ func TestUpdateVariant(t *testing.T) { Key: variant.Key, Name: variant.Name, Description: "foobar", + Attachment: []byte("foobaz"), }) require.NoError(t, err) @@ -374,6 +384,7 @@ func TestUpdateVariant(t *testing.T) { assert.Equal(t, variant.Key, updated.Key) assert.Equal(t, variant.Name, updated.Name) assert.Equal(t, "foobar", updated.Description) + assert.Equal(t, []byte("foobaz"), updated.Attachment) assert.NotZero(t, updated.CreatedAt) assert.NotZero(t, updated.UpdatedAt) @@ -403,6 +414,7 @@ func TestUpdateVariant_NotFound(t *testing.T) { Key: "foo", Name: "foo", Description: "bar", + Attachment: []byte("baz"), }) assert.EqualError(t, err, "variant \"foo\" not found") diff --git a/swagger/flipt.swagger.json b/swagger/flipt.swagger.json index 9f70c13e41..fa1a983da8 100644 --- a/swagger/flipt.swagger.json +++ b/swagger/flipt.swagger.json @@ -644,6 +644,10 @@ }, "description": { "type": "string" + }, + "attachment": { + "type": "string", + "format": "byte" } }, "required": [ @@ -739,6 +743,10 @@ }, "description": { "type": "string" + }, + "attachment": { + "type": "string", + "format": "byte" } }, "required": [ @@ -1574,6 +1582,10 @@ "updatedAt": { "type": "string", "format": "date-time" + }, + "attachment": { + "type": "string", + "format": "byte" } } }, diff --git a/ui/src/components/Flags/Flag.vue b/ui/src/components/Flags/Flag.vue index 7a4a2e98e0..4cb7340bb3 100644 --- a/ui/src/components/Flags/Flag.vue +++ b/ui/src/components/Flags/Flag.vue @@ -159,6 +159,12 @@ placeholder="Description" /> + + +