3
0

Improve automation script create/update flow

This commit is contained in:
Denis Arh
2019-08-22 21:07:03 +02:00
parent 9a428f05b4
commit e4f0c5a3b6
2 changed files with 68 additions and 54 deletions

View File

@@ -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

View File

@@ -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