Files
onepanel/server/workspace_server.go

240 lines
6.5 KiB
Go

package server
import (
"context"
"github.com/golang/protobuf/ptypes/empty"
"github.com/onepanelio/core/api"
v1 "github.com/onepanelio/core/pkg"
"github.com/onepanelio/core/pkg/util/pagination"
"github.com/onepanelio/core/pkg/util/ptr"
"github.com/onepanelio/core/server/auth"
"github.com/onepanelio/core/server/converter"
"strings"
"time"
)
type WorkspaceServer struct{}
func apiWorkspace(wt *v1.Workspace, config map[string]string) *api.Workspace {
protocol := "http://"
onepanelApiUrl := config["ONEPANEL_API_URL"]
if strings.HasPrefix(onepanelApiUrl, "https://") {
protocol = "https://"
}
res := &api.Workspace{
Uid: wt.UID,
Name: wt.Name,
CreatedAt: wt.CreatedAt.UTC().Format(time.RFC3339),
Url: protocol + wt.URL,
}
res.Parameters = converter.ParametersToAPI(wt.Parameters)
res.Status = &api.WorkspaceStatus{
Phase: string(wt.Status.Phase),
}
if wt.Status.StartedAt != nil {
res.Status.StartedAt = wt.Status.StartedAt.UTC().Format(time.RFC3339)
}
if wt.Status.PausedAt != nil {
res.Status.PausedAt = wt.Status.PausedAt.UTC().Format(time.RFC3339)
}
if wt.Status.TerminatedAt != nil {
res.Status.TerminatedAt = wt.Status.TerminatedAt.UTC().Format(time.RFC3339)
}
if len(wt.Labels) > 0 {
res.Labels = converter.MappingToKeyValue(wt.Labels)
}
if wt.WorkspaceTemplate != nil {
res.WorkspaceTemplate = apiWorkspaceTemplate(wt.WorkspaceTemplate)
}
return res
}
func NewWorkspaceServer() *WorkspaceServer {
return &WorkspaceServer{}
}
func (s *WorkspaceServer) CreateWorkspace(ctx context.Context, req *api.CreateWorkspaceRequest) (*api.Workspace, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "create", "apps", "statefulsets", "")
if err != nil || !allowed {
return nil, err
}
workspace := &v1.Workspace{
WorkspaceTemplate: &v1.WorkspaceTemplate{
UID: req.Body.WorkspaceTemplateUid,
Version: req.Body.WorkspaceTemplateVersion,
Labels: converter.APIKeyValueToLabel(req.Body.Labels),
},
}
for _, param := range req.Body.Parameters {
if param.Type == "input.hidden" {
continue
}
if param.Name == "sys-name" {
workspace.Name = param.Value
}
workspace.Parameters = append(workspace.Parameters, v1.Parameter{
Name: param.Name,
Value: ptr.String(param.Value),
})
}
workspace, err = client.CreateWorkspace(req.Namespace, workspace)
if err != nil {
return nil, err
}
sysConfig, err := client.GetSystemConfig()
if err != nil {
return nil, err
}
apiWorkspace := apiWorkspace(workspace, sysConfig)
return apiWorkspace, nil
}
func (s *WorkspaceServer) GetWorkspace(ctx context.Context, req *api.GetWorkspaceRequest) (*api.Workspace, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "get", "apps", "statefulsets", "")
if err != nil || !allowed {
return nil, err
}
workspace, err := client.GetWorkspace(req.Namespace, req.Uid)
if err != nil {
return nil, err
}
sysConfig, err := client.GetSystemConfig()
if err != nil {
return nil, err
}
apiWorkspace := apiWorkspace(workspace, sysConfig)
return apiWorkspace, nil
}
func (s *WorkspaceServer) UpdateWorkspaceStatus(ctx context.Context, req *api.UpdateWorkspaceStatusRequest) (*empty.Empty, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", "apps", "statefulsets", req.Uid)
if err != nil || !allowed {
return &empty.Empty{}, err
}
status := &v1.WorkspaceStatus{
Phase: v1.WorkspacePhase(req.Status.Phase),
}
err = client.UpdateWorkspaceStatus(req.Namespace, req.Uid, status)
return &empty.Empty{}, err
}
func (s *WorkspaceServer) UpdateWorkspace(ctx context.Context, req *api.UpdateWorkspaceRequest) (*empty.Empty, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", "apps", "statefulsets", req.Uid)
if err != nil || !allowed {
return &empty.Empty{}, err
}
var parameters []v1.Parameter
for _, param := range req.Body.Parameters {
if param.Type == "input.hidden" {
continue
}
parameters = append(parameters, v1.Parameter{
Name: param.Name,
Value: ptr.String(param.Value),
})
}
err = client.UpdateWorkspace(req.Namespace, req.Uid, parameters)
return &empty.Empty{}, err
}
func (s *WorkspaceServer) ListWorkspaces(ctx context.Context, req *api.ListWorkspaceRequest) (*api.ListWorkspaceResponse, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "list", "argoproj.io", "statefulsets", "")
if err != nil || !allowed {
return nil, err
}
paginator := pagination.NewRequest(req.Page, req.PageSize)
workspaces, err := client.ListWorkspaces(req.Namespace, &paginator)
if err != nil {
return nil, err
}
sysConfig, err := client.GetSystemConfig()
if err != nil {
return nil, err
}
var apiWorkspaces []*api.Workspace
for _, w := range workspaces {
apiWorkspaces = append(apiWorkspaces, apiWorkspace(w, sysConfig))
}
count, err := client.CountWorkspaces(req.Namespace)
if err != nil {
return nil, err
}
return &api.ListWorkspaceResponse{
Count: int32(len(apiWorkspaces)),
Workspaces: apiWorkspaces,
Page: int32(paginator.Page),
Pages: paginator.CalculatePages(count),
TotalCount: int32(count),
}, nil
}
func (s *WorkspaceServer) PauseWorkspace(ctx context.Context, req *api.PauseWorkspaceRequest) (*empty.Empty, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", "apps", "statefulsets", req.Uid)
if err != nil || !allowed {
return &empty.Empty{}, err
}
err = client.PauseWorkspace(req.Namespace, req.Uid)
return &empty.Empty{}, err
}
func (s *WorkspaceServer) ResumeWorkspace(ctx context.Context, req *api.ResumeWorkspaceRequest) (*empty.Empty, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "update", "apps", "statefulsets", req.Uid)
if err != nil || !allowed {
return &empty.Empty{}, err
}
err = client.ResumeWorkspace(req.Namespace, req.Uid)
return &empty.Empty{}, err
}
func (s *WorkspaceServer) DeleteWorkspace(ctx context.Context, req *api.DeleteWorkspaceRequest) (*empty.Empty, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "delete", "apps", "statefulsets", req.Uid)
if err != nil || !allowed {
return &empty.Empty{}, err
}
err = client.DeleteWorkspace(req.Namespace, req.Uid)
return &empty.Empty{}, err
}