Skip to content

Commit

Permalink
WIP: AdminService called by cmd_config, proto defs updated
Browse files Browse the repository at this point in the history
  • Loading branch information
safeer committed May 29, 2024
1 parent 5052a19 commit 6351020
Show file tree
Hide file tree
Showing 7 changed files with 1,231 additions and 1,073 deletions.
133 changes: 133 additions & 0 deletions backend/controller/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package controller

import (
"bytes"
"context"
"encoding/json"
"fmt"

"connectrpc.com/connect"

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"
)

type AdminService struct{}

var _ ftlv1connect.AdminServiceHandler = (*AdminService)(nil)

func NewAdminService() *AdminService {
return &AdminService{}
}

func (s *AdminService) Ping(ctx context.Context, req *connect.Request[ftlv1.PingRequest]) (*connect.Response[ftlv1.PingResponse], error) {
return connect.NewResponse(&ftlv1.PingResponse{}), nil
}

// List configuration.
func (s *AdminService) ListConfig(ctx context.Context, req *connect.Request[ftlv1.ListConfigRequest]) (*connect.Response[ftlv1.ListConfigResponse], error) {
cm := cf.ConfigFromContext(ctx)
listing, err := cm.List(ctx)
if err != nil {
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to list config: %w", err))
}

configs := []*ftlv1.ListConfigResponse_Config{}
for _, config := range listing {
module, ok := config.Module.Get()
if *req.Msg.Module != "" && module != *req.Msg.Module {
continue
}

ref := config.Name
if ok {
ref = fmt.Sprintf("%s.%s", module, config.Name)
}

cv := ""
if *req.Msg.IncludeValues {
var value any
err := 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)
}
}

configs = append(configs, &ftlv1.ListConfigResponse_Config{
RefPath: ref,
Value: &cv,
})
}
return connect.NewResponse(&ftlv1.ListConfigResponse{Configs: configs}), nil
}

// Get a config value.
func (s *AdminService) GetConfig(ctx context.Context, req *connect.Request[ftlv1.GetConfigRequest]) (*connect.Response[ftlv1.GetConfigResponse], error) {
cm := cf.ConfigFromContext(ctx)
var value any
err := cm.Get(ctx, cf.NewRef(*req.Msg.Ref.Module, req.Msg.Ref.Name), &value)
if err != nil {
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)
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
}

// Set a config value.
func (s *AdminService) SetConfig(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
if err := cm.Mutable(); err != nil {
return nil, connect.NewError(connect.CodeInternal, err)
}

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

return connect.NewResponse(&ftlv1.SetConfigResponse{}), nil
}

// Unset a config value.
func (s *AdminService) UnsetConfig(ctx context.Context, req *connect.Request[ftlv1.UnsetConfigRequest]) (*connect.Response[ftlv1.UnsetConfigResponse], error) {
cm := cf.ConfigFromContext(ctx) // TODO(saf): use cf.New to create a cm with the appropriate provider/writer
err := cm.Unset(ctx, cf.NewRef(*req.Msg.Ref.Module, req.Msg.Ref.Name))
if err != nil {
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to unset value: %w", err))
}
return connect.NewResponse(&ftlv1.UnsetConfigResponse{}), nil
}

// List secrets.
func (s *AdminService) ListSecrets(ctx context.Context, req *connect.Request[ftlv1.ListSecretsRequest]) (*connect.Response[ftlv1.ListSecretsResponse], error) {
return connect.NewResponse(&ftlv1.ListSecretsResponse{}), nil
}

// Get a secret.
func (s *AdminService) GetSecret(ctx context.Context, req *connect.Request[ftlv1.GetSecretRequest]) (*connect.Response[ftlv1.GetSecretResponse], error) {
return connect.NewResponse(&ftlv1.GetSecretResponse{}), nil
}

// Set a secret.
func (s *AdminService) SetSecret(ctx context.Context, req *connect.Request[ftlv1.SetSecretRequest]) (*connect.Response[ftlv1.SetSecretResponse], error) {
return connect.NewResponse(&ftlv1.SetSecretResponse{}), nil
}

// Unset a secret.
func (s *AdminService) UnsetSecret(ctx context.Context, req *connect.Request[ftlv1.UnsetSecretRequest]) (*connect.Response[ftlv1.UnsetSecretResponse], error) {
return connect.NewResponse(&ftlv1.UnsetSecretResponse{}), nil
}
2 changes: 2 additions & 0 deletions backend/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScali
}
logger.Debugf("Listening on %s", config.Bind)

admin := NewAdminService()
console := NewConsoleService(dal)

ingressHandler := http.StripPrefix("/ingress", svc)
Expand All @@ -136,6 +137,7 @@ func Start(ctx context.Context, config Config, runnerScaling scaling.RunnerScali
return rpc.Serve(ctx, config.Bind,
rpc.GRPC(ftlv1connect.NewVerbServiceHandler, svc),
rpc.GRPC(ftlv1connect.NewControllerServiceHandler, svc),
rpc.GRPC(ftlv1connect.NewAdminServiceHandler, admin),
rpc.GRPC(pbconsoleconnect.NewConsoleServiceHandler, console),
rpc.HTTP("/ingress/", ingressHandler),
rpc.HTTP("/", consoleHandler),
Expand Down
Loading

0 comments on commit 6351020

Please sign in to comment.