forked from raystack/optimus
-
Notifications
You must be signed in to change notification settings - Fork 1
/
project.go
134 lines (114 loc) · 4.31 KB
/
project.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package v1beta1
import (
"context"
"fmt"
"strings"
"github.com/goto/salt/log"
"github.com/goto/optimus/core/tenant"
"github.com/goto/optimus/internal/errors"
pb "github.com/goto/optimus/protos/gotocompany/optimus/core/v1beta1"
)
type ProjectHandler struct {
l log.Logger
projectService ProjectService
pb.UnimplementedProjectServiceServer
}
type ProjectService interface {
Save(context.Context, *tenant.Project) error
Get(context.Context, tenant.ProjectName) (*tenant.Project, error)
GetAll(context.Context) ([]*tenant.Project, error)
}
type TenantService interface {
GetDetails(ctx context.Context, tnnt tenant.Tenant) (*tenant.WithDetails, error)
GetSecrets(ctx context.Context, tnnt tenant.Tenant) ([]*tenant.PlainTextSecret, error)
GetSecret(ctx context.Context, tnnt tenant.Tenant, name string) (*tenant.PlainTextSecret, error)
}
func (ph *ProjectHandler) RegisterProject(ctx context.Context, req *pb.RegisterProjectRequest) (*pb.RegisterProjectResponse, error) {
project, err := fromProjectProto(req.GetProject())
if err != nil {
ph.l.Error("error adapting project: %s", err)
return nil, errors.GRPCErr(err, fmt.Sprintf("not able to register project %s", req.GetProject().Name))
}
if err := ph.projectService.Save(ctx, project); err != nil {
ph.l.Error("error saving project: %s", err)
return nil, errors.GRPCErr(err, fmt.Sprintf("not able to register project %s", req.GetProject().Name))
}
return &pb.RegisterProjectResponse{}, nil
}
func (ph *ProjectHandler) ListProjects(ctx context.Context, _ *pb.ListProjectsRequest) (*pb.ListProjectsResponse, error) {
projects, err := ph.projectService.GetAll(ctx)
if err != nil {
ph.l.Error("error getting all projects: %s", err)
return nil, errors.GRPCErr(err, "failed to retrieve saved projects")
}
var projSpecsProto []*pb.ProjectSpecification
for _, project := range projects {
projSpecsProto = append(projSpecsProto, toProjectProto(project))
}
return &pb.ListProjectsResponse{
Projects: projSpecsProto,
}, nil
}
func (ph *ProjectHandler) GetProject(ctx context.Context, req *pb.GetProjectRequest) (*pb.GetProjectResponse, error) {
projName, err := tenant.ProjectNameFrom(req.GetProjectName())
if err != nil {
ph.l.Error("error adapting project name [%s]: %s", req.GetProjectName(), err)
return nil, errors.GRPCErr(err, fmt.Sprintf("failed to retrieve project [%s]", req.GetProjectName()))
}
project, err := ph.projectService.Get(ctx, projName)
if err != nil {
ph.l.Error("error getting project [%s]: %s", projName, err)
return nil, errors.GRPCErr(err, fmt.Sprintf("failed to retrieve project [%s]", req.GetProjectName()))
}
return &pb.GetProjectResponse{
Project: toProjectProto(project),
}, nil
}
func NewProjectHandler(l log.Logger, projectService ProjectService) *ProjectHandler {
return &ProjectHandler{
l: l,
projectService: projectService,
}
}
func fromProjectProto(conf *pb.ProjectSpecification) (*tenant.Project, error) {
pConf := map[string]string{}
for key, val := range conf.GetConfig() {
pConf[strings.ToUpper(key)] = val
}
presets := make(map[string]tenant.Preset, len(conf.GetPresets()))
for name, preset := range conf.GetPresets() {
lowerName := strings.ToLower(name)
newPreset, err := tenant.NewPreset(lowerName, preset.Description, preset.GetSize(), preset.GetDelay(), preset.GetLocation(), preset.GetTruncateTo())
if err != nil {
return nil, err
}
presets[lowerName] = newPreset
}
project, err := tenant.NewProject(conf.GetName(), pConf)
if err != nil {
return nil, err
}
project.SetPresets(presets)
return project, nil
}
func toProjectProto(project *tenant.Project) *pb.ProjectSpecification {
return &pb.ProjectSpecification{
Name: project.Name().String(),
Config: project.GetConfigs(),
Presets: toProjectPresets(project.GetPresets()),
}
}
func toProjectPresets(presets map[string]tenant.Preset) map[string]*pb.ProjectSpecification_ProjectPreset {
presetPb := make(map[string]*pb.ProjectSpecification_ProjectPreset, len(presets))
for name, preset := range presets {
presetPb[name] = &pb.ProjectSpecification_ProjectPreset{
Name: preset.Name(),
Description: preset.Description(),
TruncateTo: preset.Config().TruncateTo,
Delay: preset.Config().Delay,
Size: preset.Config().Size,
Location: preset.Config().Location,
}
}
return presetPb
}