grpcApiActions.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package grpcapi
  2. import (
  3. apiv1 "github.com/OliveTin/OliveTin/gen/grpc/olivetin/api/v1"
  4. acl "github.com/OliveTin/OliveTin/internal/acl"
  5. config "github.com/OliveTin/OliveTin/internal/config"
  6. executor "github.com/OliveTin/OliveTin/internal/executor"
  7. installationinfo "github.com/OliveTin/OliveTin/internal/installationinfo"
  8. sv "github.com/OliveTin/OliveTin/internal/stringvariables"
  9. "sort"
  10. )
  11. type DashboardRenderRequest struct {
  12. AuthenticatedUser *acl.AuthenticatedUser
  13. AllowedActionTitles []string `json:"allows_action_titles"`
  14. cfg *config.Config
  15. }
  16. func buildDashboardResponse(ex *executor.Executor, cfg *config.Config, user *acl.AuthenticatedUser) *apiv1.GetDashboardComponentsResponse {
  17. res := &apiv1.GetDashboardComponentsResponse{
  18. AuthenticatedUser: user.Username,
  19. AuthenticatedUserProvider: user.Provider,
  20. }
  21. ex.MapActionIdToBindingLock.RLock()
  22. for actionId, actionBinding := range ex.MapActionIdToBinding {
  23. if !acl.IsAllowedView(cfg, user, actionBinding.Action) {
  24. continue
  25. }
  26. res.Actions = append(res.Actions, buildAction(actionId, actionBinding, user))
  27. }
  28. ex.MapActionIdToBindingLock.RUnlock()
  29. sort.Slice(res.Actions, func(i, j int) bool {
  30. if res.Actions[i].Order == res.Actions[j].Order {
  31. return res.Actions[i].Title < res.Actions[j].Title
  32. } else {
  33. return res.Actions[i].Order < res.Actions[j].Order
  34. }
  35. })
  36. rr := &DashboardRenderRequest{
  37. AuthenticatedUser: user,
  38. AllowedActionTitles: getActionTitles(res.Actions),
  39. cfg: cfg,
  40. }
  41. res.EffectivePolicy = buildEffectivePolicy(user.EffectivePolicy)
  42. res.Diagnostics = buildDiagnostics(res.EffectivePolicy.ShowDiagnostics)
  43. res.Dashboards = dashboardCfgToPb(rr)
  44. return res
  45. }
  46. func getActionTitles(actions []*apiv1.Action) []string {
  47. titles := make([]string, 0, len(actions))
  48. for _, action := range actions {
  49. titles = append(titles, action.Title)
  50. }
  51. return titles
  52. }
  53. func buildEffectivePolicy(policy *config.ConfigurationPolicy) *apiv1.EffectivePolicy {
  54. ret := &apiv1.EffectivePolicy{
  55. ShowDiagnostics: policy.ShowDiagnostics,
  56. ShowLogList: policy.ShowLogList,
  57. }
  58. return ret
  59. }
  60. func buildDiagnostics(showDiagnostics bool) *apiv1.Diagnostics {
  61. ret := &apiv1.Diagnostics{}
  62. if showDiagnostics {
  63. ret.SshFoundKey = installationinfo.Runtime.SshFoundKey
  64. ret.SshFoundConfig = installationinfo.Runtime.SshFoundConfig
  65. }
  66. return ret
  67. }
  68. func buildAction(actionId string, actionBinding *executor.ActionBinding, user *acl.AuthenticatedUser) *apiv1.Action {
  69. action := actionBinding.Action
  70. btn := apiv1.Action{
  71. Id: actionId,
  72. Title: sv.ReplaceEntityVars(actionBinding.EntityPrefix, action.Title),
  73. Icon: sv.ReplaceEntityVars(actionBinding.EntityPrefix, action.Icon),
  74. CanExec: acl.IsAllowedExec(cfg, user, action),
  75. PopupOnStart: action.PopupOnStart,
  76. Order: int32(actionBinding.ConfigOrder),
  77. }
  78. for _, cfgArg := range action.Arguments {
  79. pbArg := apiv1.ActionArgument{
  80. Name: cfgArg.Name,
  81. Title: cfgArg.Title,
  82. Type: cfgArg.Type,
  83. Description: cfgArg.Description,
  84. DefaultValue: cfgArg.Default,
  85. Choices: buildChoices(cfgArg),
  86. Suggestions: cfgArg.Suggestions,
  87. }
  88. btn.Arguments = append(btn.Arguments, &pbArg)
  89. }
  90. return &btn
  91. }
  92. func buildChoices(arg config.ActionArgument) []*apiv1.ActionArgumentChoice {
  93. if arg.Entity != "" && len(arg.Choices) == 1 {
  94. return buildChoicesEntity(arg.Choices[0], arg.Entity)
  95. } else {
  96. return buildChoicesSimple(arg.Choices)
  97. }
  98. }
  99. func buildChoicesEntity(firstChoice config.ActionArgumentChoice, entityTitle string) []*apiv1.ActionArgumentChoice {
  100. ret := []*apiv1.ActionArgumentChoice{}
  101. entityCount := sv.GetEntityCount(entityTitle)
  102. for i := 0; i < entityCount; i++ {
  103. prefix := sv.GetEntityPrefix(entityTitle, i)
  104. ret = append(ret, &apiv1.ActionArgumentChoice{
  105. Value: sv.ReplaceEntityVars(prefix, firstChoice.Value),
  106. Title: sv.ReplaceEntityVars(prefix, firstChoice.Title),
  107. })
  108. }
  109. return ret
  110. }
  111. func buildChoicesSimple(choices []config.ActionArgumentChoice) []*apiv1.ActionArgumentChoice {
  112. ret := []*apiv1.ActionArgumentChoice{}
  113. for _, cfgChoice := range choices {
  114. pbChoice := apiv1.ActionArgumentChoice{
  115. Value: cfgChoice.Value,
  116. Title: cfgChoice.Title,
  117. }
  118. ret = append(ret, &pbChoice)
  119. }
  120. return ret
  121. }