From 678853f8e89447323b8b2ede1cab70172a9871f5 Mon Sep 17 00:00:00 2001 From: Safeer Jiwan Date: Wed, 29 May 2024 13:36:53 -0700 Subject: [PATCH] WIP: PR comments addressed, still unable to set config --- backend/controller/admin.go | 54 ++++++----------- backend/controller/controller.go | 3 - backend/protos/xyz/block/ftl/v1/ftl.pb.go | 60 +++++++++---------- backend/protos/xyz/block/ftl/v1/ftl.proto | 15 ++--- cmd/ftl/cmd_config.go | 20 ++++--- cmd/ftl/cmd_serve.go | 2 - cmd/ftl/main.go | 2 - .../protos/xyz/block/ftl/v1/ftl_connect.ts | 3 +- .../src/protos/xyz/block/ftl/v1/ftl_pb.ts | 36 +++++------ 9 files changed, 90 insertions(+), 105 deletions(-) diff --git a/backend/controller/admin.go b/backend/controller/admin.go index 9a907d90df..989e5e467b 100644 --- a/backend/controller/admin.go +++ b/backend/controller/admin.go @@ -1,7 +1,6 @@ package controller import ( - "bytes" "context" "encoding/json" "fmt" @@ -11,7 +10,6 @@ import ( ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" cf "github.com/TBD54566975/ftl/common/configuration" - "github.com/TBD54566975/ftl/internal/log" ) type AdminService struct { @@ -32,7 +30,7 @@ func (s *AdminService) Ping(ctx context.Context, req *connect.Request[ftlv1.Ping return connect.NewResponse(&ftlv1.PingResponse{}), nil } -// List configuration. +// ConfigList returns the list of configuration values, optionally filtered by module. func (s *AdminService) ConfigList(ctx context.Context, req *connect.Request[ftlv1.ListConfigRequest]) (*connect.Response[ftlv1.ListConfigResponse], error) { listing, err := s.cm.List(ctx) if err != nil { @@ -51,27 +49,26 @@ func (s *AdminService) ConfigList(ctx context.Context, req *connect.Request[ftlv ref = fmt.Sprintf("%s.%s", module, config.Name) } - cv := "" + var cv []byte if *req.Msg.IncludeValues { var value any err := s.cm.Get(ctx, config.Ref, &value) if err != nil { return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to get value: %w", err)) } else { - data, _ := json.Marshal(value) - cv = string(data) + cv, _ = json.Marshal(value) } } configs = append(configs, &ftlv1.ListConfigResponse_Config{ RefPath: ref, - Value: &cv, + Value: cv, }) } return connect.NewResponse(&ftlv1.ListConfigResponse{Configs: configs}), nil } -// Get a config value. +// ConfigGet returns the configuration value for a given ref string. func (s *AdminService) ConfigGet(ctx context.Context, req *connect.Request[ftlv1.GetConfigRequest]) (*connect.Response[ftlv1.GetConfigResponse], error) { var value any err := s.cm.Get(ctx, cf.NewRef(*req.Msg.Ref.Module, req.Msg.Ref.Name), &value) @@ -79,49 +76,36 @@ func (s *AdminService) ConfigGet(ctx context.Context, req *connect.Request[ftlv1 return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to get value: %w", err)) } - buf := new(bytes.Buffer) - enc := json.NewEncoder(buf) - enc.SetIndent("", " ") - err = enc.Encode(value) + vb, err := json.MarshalIndent(value, "", " ") if err != nil { return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to encode value: %w", err)) } - return connect.NewResponse(&ftlv1.GetConfigResponse{Value: buf.String()}), nil + return connect.NewResponse(&ftlv1.GetConfigResponse{Value: vb}), nil } -// Set a config value. +// ConfigSet sets the configuration at the given ref to the provided value. func (s *AdminService) ConfigSet(ctx context.Context, req *connect.Request[ftlv1.SetConfigRequest]) (*connect.Response[ftlv1.SetConfigResponse], error) { - // cm := cf.ConfigFromContext(ctx) // TODO(saf): use cf.New to create a cm with the appropriate provider/writer - var err error - // var providerKey string - // switch *req.Msg.Provider { - // case ftlv1.ConfigProvider_CONFIG_ENVAR: - // providerKey = "envar" - // case ftlv1.ConfigProvider_CONFIG_INLINE: - // providerKey = "inline" - // } - - logger := log.FromContext(ctx) - logger.Warnf("cm pre-mutable %+v", s.cm) - if err := s.cm.Mutable(); err != nil { + // TODO(saf): use req.Msg.Provider to update / create a manager with the correct provider + cm := s.cm + + if err := cm.Mutable(); err != nil { return nil, connect.NewError(connect.CodeInternal, err) } - logger.Warnf("cm post-mutable %+v", s.cm) - err = s.cm.Set(ctx, cf.NewRef(*req.Msg.Ref.Module, req.Msg.Ref.Name), req.Msg.Value) + err = cm.Set(ctx, cf.NewRef(*req.Msg.Ref.Module, req.Msg.Ref.Name), req.Msg.Value) if err != nil { return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to set value: %w", err)) } - // TODO save the updated config + // TODO(saf) save the updated config return connect.NewResponse(&ftlv1.SetConfigResponse{}), nil } -// Unset a config value. +// ConfigUnset unsets the config value at the given ref. func (s *AdminService) ConfigUnset(ctx context.Context, req *connect.Request[ftlv1.UnsetConfigRequest]) (*connect.Response[ftlv1.UnsetConfigResponse], error) { err := s.cm.Unset(ctx, cf.NewRef(*req.Msg.Ref.Module, req.Msg.Ref.Name)) if err != nil { @@ -130,22 +114,22 @@ func (s *AdminService) ConfigUnset(ctx context.Context, req *connect.Request[ftl return connect.NewResponse(&ftlv1.UnsetConfigResponse{}), nil } -// List secrets. +// SecretsList returns the list of secrets, optionally filtered by module. func (s *AdminService) SecretsList(ctx context.Context, req *connect.Request[ftlv1.ListSecretsRequest]) (*connect.Response[ftlv1.ListSecretsResponse], error) { return connect.NewResponse(&ftlv1.ListSecretsResponse{}), nil } -// Get a secret. +// SecretGet returns the secret value for a given ref string. func (s *AdminService) SecretGet(ctx context.Context, req *connect.Request[ftlv1.GetSecretRequest]) (*connect.Response[ftlv1.GetSecretResponse], error) { return connect.NewResponse(&ftlv1.GetSecretResponse{}), nil } -// Set a secret. +// SecretSet sets the secret at the given ref to the provided value. func (s *AdminService) SecretSet(ctx context.Context, req *connect.Request[ftlv1.SetSecretRequest]) (*connect.Response[ftlv1.SetSecretResponse], error) { return connect.NewResponse(&ftlv1.SetSecretResponse{}), nil } -// Unset a secret. +// SecretUnset unsets the secret value at the given ref. func (s *AdminService) SecretUnset(ctx context.Context, req *connect.Request[ftlv1.UnsetSecretRequest]) (*connect.Response[ftlv1.UnsetSecretResponse], error) { return connect.NewResponse(&ftlv1.UnsetSecretResponse{}), nil } diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 64d50a537b..c7b5b9dc24 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -129,9 +129,6 @@ func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScali cm := cf.ConfigFromContext(ctx) sm := cf.SecretsFromContext(ctx) - logger.Warnf("config manager: %+v", cm) - logger.Warnf("secrets manager: %+v", sm) - admin := NewAdminService(cm, sm) console := NewConsoleService(dal) diff --git a/backend/protos/xyz/block/ftl/v1/ftl.pb.go b/backend/protos/xyz/block/ftl/v1/ftl.pb.go index 8152730599..839be5f790 100644 --- a/backend/protos/xyz/block/ftl/v1/ftl.pb.go +++ b/backend/protos/xyz/block/ftl/v1/ftl.pb.go @@ -2768,7 +2768,7 @@ type GetConfigResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` } func (x *GetConfigResponse) Reset() { @@ -2803,11 +2803,11 @@ func (*GetConfigResponse) Descriptor() ([]byte, []int) { return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{47} } -func (x *GetConfigResponse) GetValue() string { +func (x *GetConfigResponse) GetValue() []byte { if x != nil { return x.Value } - return "" + return nil } type SetConfigRequest struct { @@ -2817,7 +2817,7 @@ type SetConfigRequest struct { Provider *ConfigProvider `protobuf:"varint,1,opt,name=provider,proto3,enum=xyz.block.ftl.v1.ConfigProvider,oneof" json:"provider,omitempty"` Ref *ConfigRef `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"` - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` } func (x *SetConfigRequest) Reset() { @@ -2866,11 +2866,11 @@ func (x *SetConfigRequest) GetRef() *ConfigRef { return nil } -func (x *SetConfigRequest) GetValue() string { +func (x *SetConfigRequest) GetValue() []byte { if x != nil { return x.Value } - return "" + return nil } type SetConfigResponse struct { @@ -3174,7 +3174,7 @@ type GetSecretResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` } func (x *GetSecretResponse) Reset() { @@ -3209,11 +3209,11 @@ func (*GetSecretResponse) Descriptor() ([]byte, []int) { return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{55} } -func (x *GetSecretResponse) GetValue() string { +func (x *GetSecretResponse) GetValue() []byte { if x != nil { return x.Value } - return "" + return nil } type SetSecretRequest struct { @@ -3223,7 +3223,7 @@ type SetSecretRequest struct { Provider *SecretProvider `protobuf:"varint,1,opt,name=provider,proto3,enum=xyz.block.ftl.v1.SecretProvider,oneof" json:"provider,omitempty"` Ref *ConfigRef `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"` - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` } func (x *SetSecretRequest) Reset() { @@ -3272,11 +3272,11 @@ func (x *SetSecretRequest) GetRef() *ConfigRef { return nil } -func (x *SetSecretRequest) GetValue() string { +func (x *SetSecretRequest) GetValue() []byte { if x != nil { return x.Value } - return "" + return nil } type SetSecretResponse struct { @@ -4156,8 +4156,8 @@ type ListConfigResponse_Config struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RefPath string `protobuf:"bytes,1,opt,name=refPath,proto3" json:"refPath,omitempty"` - Value *string `protobuf:"bytes,2,opt,name=value,proto3,oneof" json:"value,omitempty"` + RefPath string `protobuf:"bytes,1,opt,name=refPath,proto3" json:"refPath,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3,oneof" json:"value,omitempty"` } func (x *ListConfigResponse_Config) Reset() { @@ -4199,11 +4199,11 @@ func (x *ListConfigResponse_Config) GetRefPath() string { return "" } -func (x *ListConfigResponse_Config) GetValue() string { - if x != nil && x.Value != nil { - return *x.Value +func (x *ListConfigResponse_Config) GetValue() []byte { + if x != nil { + return x.Value } - return "" + return nil } type ListSecretsResponse_Secret struct { @@ -4211,8 +4211,8 @@ type ListSecretsResponse_Secret struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - RefPath string `protobuf:"bytes,1,opt,name=refPath,proto3" json:"refPath,omitempty"` - Value *string `protobuf:"bytes,2,opt,name=value,proto3,oneof" json:"value,omitempty"` + RefPath string `protobuf:"bytes,1,opt,name=refPath,proto3" json:"refPath,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3,oneof" json:"value,omitempty"` } func (x *ListSecretsResponse_Secret) Reset() { @@ -4254,11 +4254,11 @@ func (x *ListSecretsResponse_Secret) GetRefPath() string { return "" } -func (x *ListSecretsResponse_Secret) GetValue() string { - if x != nil && x.Value != nil { - return *x.Value +func (x *ListSecretsResponse_Secret) GetValue() []byte { + if x != nil { + return x.Value } - return "" + return nil } var File_xyz_block_ftl_v1_ftl_proto protoreflect.FileDescriptor @@ -4680,7 +4680,7 @@ var file_xyz_block_ftl_v1_ftl_proto_rawDesc = []byte{ 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x66, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, + 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, @@ -4692,7 +4692,7 @@ var file_xyz_block_ftl_v1_ftl_proto_rawDesc = []byte{ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x66, 0x52, 0x03, 0x72, 0x65, 0x66, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x29, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, @@ -4702,7 +4702,7 @@ var file_xyz_block_ftl_v1_ftl_proto_rawDesc = []byte{ 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x66, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x43, @@ -4738,7 +4738,7 @@ var file_xyz_block_ftl_v1_ftl_proto_rawDesc = []byte{ 0x1a, 0x47, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x66, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, + 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, @@ -4751,7 +4751,7 @@ var file_xyz_block_ftl_v1_ftl_proto_rawDesc = []byte{ 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x29, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x74, + 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, @@ -4760,7 +4760,7 @@ var file_xyz_block_ftl_v1_ftl_proto_rawDesc = []byte{ 0x12, 0x2d, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x66, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x65, diff --git a/backend/protos/xyz/block/ftl/v1/ftl.proto b/backend/protos/xyz/block/ftl/v1/ftl.proto index 7dbddd120b..9802e678f3 100644 --- a/backend/protos/xyz/block/ftl/v1/ftl.proto +++ b/backend/protos/xyz/block/ftl/v1/ftl.proto @@ -405,7 +405,7 @@ message ListConfigRequest { message ListConfigResponse { message Config { string refPath = 1; - optional string value = 2; + optional bytes value = 2; } repeated Config configs = 1; } @@ -415,13 +415,13 @@ message GetConfigRequest { ConfigRef ref = 2; } message GetConfigResponse { - string value = 1; + bytes value = 1; } message SetConfigRequest { optional ConfigProvider provider = 1; ConfigRef ref = 2; - string value = 3; + bytes value = 3; } message SetConfigResponse {} @@ -453,7 +453,7 @@ message ListSecretsRequest { message ListSecretsResponse { message Secret { string refPath = 1; - optional string value = 2; + optional bytes value = 2; } repeated Secret secrets = 1; } @@ -463,13 +463,13 @@ message GetSecretRequest { ConfigRef ref = 2; } message GetSecretResponse { - string value = 1; + bytes value = 1; } message SetSecretRequest { optional SecretProvider provider = 1; ConfigRef ref = 2; - string value = 3; + bytes value = 3; } message SetSecretResponse {} @@ -479,7 +479,8 @@ message UnsetSecretRequest { } message UnsetSecretResponse {} -// AdminService centralizes project configuration access and provides CRUD operations. +// AdminService is the service that provides and updates admin data. For example, +// it is used to encapsulate configuration and secrets. service AdminService { rpc Ping(PingRequest) returns (PingResponse) { option idempotency_level = NO_SIDE_EFFECTS; diff --git a/cmd/ftl/cmd_config.go b/cmd/ftl/cmd_config.go index 375078203b..d539d01b6d 100644 --- a/cmd/ftl/cmd_config.go +++ b/cmd/ftl/cmd_config.go @@ -35,7 +35,7 @@ type configListCmd struct { Module string `optional:"" arg:"" placeholder:"MODULE" help:"List configuration only in this module."` } -func (s *configListCmd) Run(ctx context.Context, scmd *configCmd, admin ftlv1connect.AdminServiceClient) error { +func (s *configListCmd) Run(ctx context.Context, admin ftlv1connect.AdminServiceClient) error { resp, err := admin.ConfigList(ctx, connect.NewRequest(&ftlv1.ListConfigRequest{ // Provider: TODO(saf) Module: &s.Module, @@ -47,8 +47,8 @@ func (s *configListCmd) Run(ctx context.Context, scmd *configCmd, admin ftlv1con for _, config := range resp.Msg.Configs { fmt.Printf("%s", config.RefPath) - if config.Value != nil && *config.Value != "" { - fmt.Printf(" = %s\n", *config.Value) + if config.Value != nil && len(config.Value) > 0 { + fmt.Printf(" = %s\n", config.Value) } else { fmt.Println() } @@ -66,7 +66,7 @@ Returns a JSON-encoded configuration value. ` } -func (s *configGetCmd) Run(ctx context.Context, scmd *configCmd, admin ftlv1connect.AdminServiceClient) error { +func (s *configGetCmd) Run(ctx context.Context, admin ftlv1connect.AdminServiceClient) error { module := s.Ref.Module.Default("") resp, err := admin.ConfigGet(ctx, connect.NewRequest(&ftlv1.GetConfigRequest{ // Provider: TODO(saf) @@ -78,7 +78,13 @@ func (s *configGetCmd) Run(ctx context.Context, scmd *configCmd, admin ftlv1conn if err != nil { return fmt.Errorf("failed to get config: %w", err) } - fmt.Println(resp.Msg.Value) + + var value any + err = json.Unmarshal(resp.Msg.Value, &value) + if err != nil { + return fmt.Errorf("failed to unmarshal config value: %w", err) + } + fmt.Println(value) return nil } @@ -100,13 +106,13 @@ func (s *configSetCmd) Run(ctx context.Context, scmd *configCmd, admin ftlv1conn } } - var configValue string + var configValue []byte if s.JSON { if err := json.Unmarshal(config, &configValue); err != nil { return fmt.Errorf("config is not valid JSON: %w", err) } } else { - configValue = string(config) + configValue = config } var cp ftlv1.ConfigProvider diff --git a/cmd/ftl/cmd_serve.go b/cmd/ftl/cmd_serve.go index 4b62974d37..27bfd9e1d2 100644 --- a/cmd/ftl/cmd_serve.go +++ b/cmd/ftl/cmd_serve.go @@ -38,8 +38,6 @@ type serveCmd struct { Stop bool `help:"Stop the running FTL instance. Can be used with --background to restart the server" default:"false"` StartupTimeout time.Duration `help:"Timeout for the server to start up." default:"1m"` controller.CommonConfig - // cf.DefaultConfigMixin - // cf.DefaultSecretsMixin } const ftlContainerName = "ftl-db-1" diff --git a/cmd/ftl/main.go b/cmd/ftl/main.go index 6fdc0397d5..1f994203d4 100644 --- a/cmd/ftl/main.go +++ b/cmd/ftl/main.go @@ -92,7 +92,6 @@ func main() { // Add config manager to context. cm, err := cf.NewConfigurationManager(ctx, cr) - logger.Warnf("main config: %+v", cm) if err != nil { kctx.Fatalf(err.Error()) } @@ -100,7 +99,6 @@ func main() { // Add secrets manager to context. sm, err := cf.NewSecretsManager(ctx, sr) - logger.Warnf("main secrets: %+v", sm) if err != nil { kctx.Fatalf(err.Error()) } diff --git a/frontend/src/protos/xyz/block/ftl/v1/ftl_connect.ts b/frontend/src/protos/xyz/block/ftl/v1/ftl_connect.ts index 6fab05d006..a391a62351 100644 --- a/frontend/src/protos/xyz/block/ftl/v1/ftl_connect.ts +++ b/frontend/src/protos/xyz/block/ftl/v1/ftl_connect.ts @@ -308,7 +308,8 @@ export const RunnerService = { } as const; /** - * AdminService centralizes project configuration access and provides CRUD operations. + * AdminService is the service that provides and updates admin data. For example, + * it is used to encapsulate configuration and secrets. * * @generated from service xyz.block.ftl.v1.AdminService */ diff --git a/frontend/src/protos/xyz/block/ftl/v1/ftl_pb.ts b/frontend/src/protos/xyz/block/ftl/v1/ftl_pb.ts index 0897559333..f7c941b03d 100644 --- a/frontend/src/protos/xyz/block/ftl/v1/ftl_pb.ts +++ b/frontend/src/protos/xyz/block/ftl/v1/ftl_pb.ts @@ -2649,9 +2649,9 @@ export class ListConfigResponse_Config extends Message) { super(); @@ -2662,7 +2662,7 @@ export class ListConfigResponse_Config extends Message [ { no: 1, name: "refPath", kind: "scalar", T: 9 /* ScalarType.STRING */ }, - { no: 2, name: "value", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 2, name: "value", kind: "scalar", T: 12 /* ScalarType.BYTES */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): ListConfigResponse_Config { @@ -2730,9 +2730,9 @@ export class GetConfigRequest extends Message { */ export class GetConfigResponse extends Message { /** - * @generated from field: string value = 1; + * @generated from field: bytes value = 1; */ - value = ""; + value = new Uint8Array(0); constructor(data?: PartialMessage) { super(); @@ -2742,7 +2742,7 @@ export class GetConfigResponse extends Message { static readonly runtime: typeof proto3 = proto3; static readonly typeName = "xyz.block.ftl.v1.GetConfigResponse"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ - { no: 1, name: "value", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 1, name: "value", kind: "scalar", T: 12 /* ScalarType.BYTES */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): GetConfigResponse { @@ -2777,9 +2777,9 @@ export class SetConfigRequest extends Message { ref?: ConfigRef; /** - * @generated from field: string value = 3; + * @generated from field: bytes value = 3; */ - value = ""; + value = new Uint8Array(0); constructor(data?: PartialMessage) { super(); @@ -2791,7 +2791,7 @@ export class SetConfigRequest extends Message { static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "provider", kind: "enum", T: proto3.getEnumType(ConfigProvider), opt: true }, { no: 2, name: "ref", kind: "message", T: ConfigRef }, - { no: 3, name: "value", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "value", kind: "scalar", T: 12 /* ScalarType.BYTES */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): SetConfigRequest { @@ -3012,9 +3012,9 @@ export class ListSecretsResponse_Secret extends Message) { super(); @@ -3025,7 +3025,7 @@ export class ListSecretsResponse_Secret extends Message [ { no: 1, name: "refPath", kind: "scalar", T: 9 /* ScalarType.STRING */ }, - { no: 2, name: "value", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 2, name: "value", kind: "scalar", T: 12 /* ScalarType.BYTES */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): ListSecretsResponse_Secret { @@ -3093,9 +3093,9 @@ export class GetSecretRequest extends Message { */ export class GetSecretResponse extends Message { /** - * @generated from field: string value = 1; + * @generated from field: bytes value = 1; */ - value = ""; + value = new Uint8Array(0); constructor(data?: PartialMessage) { super(); @@ -3105,7 +3105,7 @@ export class GetSecretResponse extends Message { static readonly runtime: typeof proto3 = proto3; static readonly typeName = "xyz.block.ftl.v1.GetSecretResponse"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ - { no: 1, name: "value", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 1, name: "value", kind: "scalar", T: 12 /* ScalarType.BYTES */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): GetSecretResponse { @@ -3140,9 +3140,9 @@ export class SetSecretRequest extends Message { ref?: ConfigRef; /** - * @generated from field: string value = 3; + * @generated from field: bytes value = 3; */ - value = ""; + value = new Uint8Array(0); constructor(data?: PartialMessage) { super(); @@ -3154,7 +3154,7 @@ export class SetSecretRequest extends Message { static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "provider", kind: "enum", T: proto3.getEnumType(SecretProvider), opt: true }, { no: 2, name: "ref", kind: "message", T: ConfigRef }, - { no: 3, name: "value", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "value", kind: "scalar", T: 12 /* ScalarType.BYTES */ }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): SetSecretRequest {