Improve automation script create/update flow
This commit is contained in:
@@ -28,6 +28,8 @@ type (
|
||||
}
|
||||
|
||||
automationScriptAccessController interface {
|
||||
CanGrant(context.Context) bool
|
||||
|
||||
CanReadNamespace(context.Context, *types.Namespace) bool
|
||||
|
||||
CanCreateAutomationScript(context.Context, *types.Namespace) bool
|
||||
@@ -54,21 +56,15 @@ func AutomationScript(sm automationScriptManager) automationScript {
|
||||
}
|
||||
|
||||
func (svc automationScript) FindByID(ctx context.Context, namespaceID, scriptID uint64) (*automation.Script, error) {
|
||||
if _, err := svc.loadNamespace(ctx, namespaceID); err != nil {
|
||||
if _, s, err := svc.loadCombo(ctx, namespaceID, scriptID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if script, err := svc.scriptManager.FindScriptByID(ctx, scriptID); err != nil {
|
||||
return nil, err
|
||||
} else if !svc.ac.CanReadAutomationScript(ctx, script) {
|
||||
return nil, ErrNoCreatePermissions.withStack()
|
||||
} else {
|
||||
return script, nil
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (svc automationScript) Find(ctx context.Context, namespaceID uint64, f automation.ScriptFilter) (automation.ScriptSet, automation.ScriptFilter, error) {
|
||||
if _, err := svc.loadNamespace(ctx, namespaceID); err != nil {
|
||||
if _, _, err := svc.loadCombo(ctx, namespaceID, 0); err != nil {
|
||||
return nil, f, err
|
||||
}
|
||||
|
||||
@@ -81,47 +77,80 @@ func (svc automationScript) Find(ctx context.Context, namespaceID uint64, f auto
|
||||
return svc.scriptManager.FindScripts(ctx, f)
|
||||
}
|
||||
|
||||
func (svc automationScript) Create(ctx context.Context, namespaceID uint64, s *automation.Script) (err error) {
|
||||
if ns, err := svc.loadNamespace(ctx, namespaceID); err != nil {
|
||||
func (svc automationScript) Create(ctx context.Context, namespaceID uint64, mod *automation.Script) (err error) {
|
||||
if ns, _, err := svc.loadCombo(ctx, namespaceID, 0); err != nil {
|
||||
return err
|
||||
} else if !svc.ac.CanCreateAutomationScript(ctx, ns) {
|
||||
return ErrNoCreatePermissions.withStack()
|
||||
}
|
||||
|
||||
return svc.scriptManager.CreateScript(ctx, s)
|
||||
if mod.RunAs > 0 {
|
||||
if !svc.ac.CanGrant(ctx) {
|
||||
return ErrNoGrantPermissions
|
||||
}
|
||||
}
|
||||
|
||||
return svc.scriptManager.CreateScript(ctx, mod)
|
||||
}
|
||||
|
||||
func (svc automationScript) Update(ctx context.Context, namespaceID uint64, s *automation.Script) (err error) {
|
||||
if _, err := svc.loadNamespace(ctx, namespaceID); err != nil {
|
||||
func (svc automationScript) Update(ctx context.Context, namespaceID uint64, mod *automation.Script) (err error) {
|
||||
if _, s, err := svc.loadCombo(ctx, namespaceID, mod.ID); err != nil {
|
||||
return err
|
||||
} else if !svc.ac.CanUpdateAutomationScript(ctx, s) {
|
||||
return ErrNoCreatePermissions.withStack()
|
||||
}
|
||||
} else {
|
||||
// Users need to have grant privileges to
|
||||
// set script runner
|
||||
if mod.RunAs != s.RunAs {
|
||||
if !svc.ac.CanGrant(ctx) {
|
||||
return ErrNoGrantPermissions
|
||||
}
|
||||
}
|
||||
|
||||
return svc.scriptManager.UpdateScript(ctx, s)
|
||||
s.Name = mod.Name
|
||||
s.SourceRef = mod.SourceRef
|
||||
s.Source = mod.Source
|
||||
s.Async = mod.Async
|
||||
s.RunAs = mod.RunAs
|
||||
s.RunInUA = mod.RunInUA
|
||||
s.Timeout = mod.Timeout
|
||||
s.Critical = mod.Critical
|
||||
s.Enabled = mod.Enabled
|
||||
|
||||
return svc.scriptManager.UpdateScript(ctx, s)
|
||||
}
|
||||
}
|
||||
|
||||
func (svc automationScript) Delete(ctx context.Context, namespaceID uint64, s *automation.Script) (err error) {
|
||||
if _, err := svc.loadNamespace(ctx, namespaceID); err != nil {
|
||||
func (svc automationScript) Delete(ctx context.Context, namespaceID, scriptID uint64) (err error) {
|
||||
if _, s, err := svc.loadCombo(ctx, namespaceID, scriptID); err != nil {
|
||||
return err
|
||||
} else if !svc.ac.CanDeleteAutomationScript(ctx, s) {
|
||||
return ErrNoCreatePermissions.withStack()
|
||||
} else {
|
||||
return svc.scriptManager.DeleteScript(ctx, s)
|
||||
}
|
||||
|
||||
return svc.scriptManager.DeleteScript(ctx, s)
|
||||
}
|
||||
|
||||
func (svc automationScript) loadNamespace(ctx context.Context, namespaceID uint64) (ns *types.Namespace, err error) {
|
||||
func (svc automationScript) loadCombo(ctx context.Context, namespaceID, scriptID uint64) (ns *types.Namespace, s *automation.Script, err error) {
|
||||
if namespaceID == 0 {
|
||||
return nil, ErrNamespaceRequired.withStack()
|
||||
err = ErrNamespaceRequired.withStack()
|
||||
return
|
||||
}
|
||||
|
||||
if ns, err = svc.ns.With(ctx).FindByID(namespaceID); err != nil {
|
||||
return
|
||||
} else if !svc.ac.CanReadNamespace(ctx, ns) {
|
||||
err = ErrNoReadPermissions.withStack()
|
||||
return
|
||||
}
|
||||
|
||||
if !svc.ac.CanReadNamespace(ctx, ns) {
|
||||
return nil, ErrNoReadPermissions.withStack()
|
||||
if scriptID > 0 {
|
||||
if s, err = svc.scriptManager.FindScriptByID(ctx, scriptID); err != nil {
|
||||
return
|
||||
} else if !svc.ac.CanReadAutomationScript(ctx, s) {
|
||||
err = ErrNoCreatePermissions.withStack()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -65,7 +65,7 @@ type (
|
||||
Find(context.Context, uint64, automation.ScriptFilter) (automation.ScriptSet, automation.ScriptFilter, error)
|
||||
Create(context.Context, uint64, *automation.Script) error
|
||||
Update(context.Context, uint64, *automation.Script) error
|
||||
Delete(context.Context, uint64, *automation.Script) error
|
||||
Delete(context.Context, uint64, uint64) error
|
||||
}
|
||||
|
||||
automationScriptRunner interface {
|
||||
@@ -148,33 +148,26 @@ func (ctrl AutomationScript) Read(ctx context.Context, r *request.AutomationScri
|
||||
}
|
||||
|
||||
func (ctrl AutomationScript) Update(ctx context.Context, r *request.AutomationScriptUpdate) (interface{}, error) {
|
||||
script, err := ctrl.scripts.FindByID(ctx, r.NamespaceID, r.ScriptID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "can not update script")
|
||||
mod := &automation.Script{
|
||||
ID: r.ScriptID,
|
||||
Name: r.Name,
|
||||
SourceRef: r.SourceRef,
|
||||
Source: r.Source,
|
||||
Async: r.Async,
|
||||
RunAs: r.RunAs,
|
||||
RunInUA: r.RunInUA,
|
||||
Timeout: r.Timeout,
|
||||
Critical: r.Critical,
|
||||
Enabled: r.Enabled,
|
||||
}
|
||||
|
||||
script.Name = r.Name
|
||||
script.SourceRef = r.SourceRef
|
||||
script.Source = r.Source
|
||||
script.Async = r.Async
|
||||
script.RunAs = r.RunAs
|
||||
script.RunInUA = r.RunInUA
|
||||
script.Timeout = r.Timeout
|
||||
script.Critical = r.Critical
|
||||
script.Enabled = r.Enabled
|
||||
mod.AddTrigger(automation.STMS_UPDATE, r.Triggers...)
|
||||
|
||||
script.AddTrigger(automation.STMS_UPDATE, r.Triggers...)
|
||||
|
||||
return ctrl.makePayload(ctx, script, ctrl.scripts.Update(ctx, r.NamespaceID, script))
|
||||
return ctrl.makePayload(ctx, mod, ctrl.scripts.Update(ctx, r.NamespaceID, mod))
|
||||
}
|
||||
|
||||
func (ctrl AutomationScript) Delete(ctx context.Context, r *request.AutomationScriptDelete) (interface{}, error) {
|
||||
script, err := ctrl.scripts.FindByID(ctx, r.NamespaceID, r.ScriptID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "can not delete script")
|
||||
}
|
||||
|
||||
return resputil.OK(), ctrl.scripts.Delete(ctx, r.NamespaceID, script)
|
||||
return resputil.OK(), ctrl.scripts.Delete(ctx, r.NamespaceID, r.ScriptID)
|
||||
}
|
||||
|
||||
func (ctrl AutomationScript) Runnable(ctx context.Context, r *request.AutomationScriptRunnable) (interface{}, error) {
|
||||
@@ -239,10 +232,6 @@ func (ctrl AutomationScript) Run(ctx context.Context, r *request.AutomationScrip
|
||||
// When record was passed return it.
|
||||
if record != nil {
|
||||
rval.Record = record
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return rval, err
|
||||
@@ -265,10 +254,6 @@ func (ctrl AutomationScript) Test(ctx context.Context, r *request.AutomationScri
|
||||
// When record was passed return it.
|
||||
if record != nil {
|
||||
rval.Record = record
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return rval, err
|
||||
|
||||
Reference in New Issue
Block a user