Skip to content

Commit

Permalink
feat: add flag MergeBuiltinActions to include all actions
Browse files Browse the repository at this point in the history
Signed-off-by: ashutosh16 <[email protected]>
  • Loading branch information
ashutosh16 committed Sep 3, 2024
1 parent 9af0ff5 commit f1aa48e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 36 deletions.
18 changes: 18 additions & 0 deletions docs/operator-manual/resource_actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,24 @@ The `discovery.lua` script must return a table where the key name represents the

Each action name must be represented in the list of `definitions` with an accompanying `action.lua` script to control the resource modifications. The `obj` is a global variable which contains the resource. Each action script returns an optionally modified version of the resource. In this example, we are simply setting `.spec.suspend` to either `true` or `false`.

!!! important
If you might want to retain the prebuilt actions along with your own actions in configmap.
In such cases, you can provide the key `mergeBuiltinActions` in the `discovery.lua` script and set it to `true`. This
will merge the custom actions with the built-in actions. If the key is not provided or set to `false`, the default
behavior is to override the built-in actions with the custom actions.

resource.customizations.actions.argoproj.io_Rollout: |
mergeBuiltinActions: true
discovery.lua: |
actions = {}
actions["custom-action"] = {}
return actions
definitions:
- name: custom-action
action.lua: |
obj.spec.template.metadata.annotations["date"] = os.date()
return obj

#### Creating new resources with a custom action

!!! important
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/application/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,7 @@ func (o *ResourceOverride) GetActions() (ResourceActions, error) {
type ResourceActions struct {
ActionDiscoveryLua string `json:"discovery.lua,omitempty" yaml:"discovery.lua,omitempty" protobuf:"bytes,1,opt,name=actionDiscoveryLua"`
Definitions []ResourceActionDefinition `json:"definitions,omitempty" protobuf:"bytes,2,rep,name=definitions"`
MergeBuiltinActions bool `json:"mergeBuiltinActions,omitempty" yaml:"mergeBuiltinActions,omitempty" protobuf:"bytes,3,opt,name=mergeBuiltinActions"`
}

// TODO: describe this type
Expand Down
96 changes: 60 additions & 36 deletions util/lua/lua.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,48 +275,56 @@ func cleanReturnedArray(newObj, obj []interface{}) []interface{} {
return arrayToReturn
}

func (vm VM) ExecuteResourceActionDiscovery(obj *unstructured.Unstructured, script string) ([]appv1.ResourceAction, error) {
l, err := vm.runLua(obj, script)
if err != nil {
return nil, err
func (vm VM) ExecuteResourceActionDiscovery(obj *unstructured.Unstructured, script []string) ([]appv1.ResourceAction, error) {
if len(script) == 0 {
return nil, fmt.Errorf("no action discovery script provided")
}
returnValue := l.Get(-1)
if returnValue.Type() == lua.LTTable {
jsonBytes, err := luajson.Encode(returnValue)
if err != nil {
return nil, err
}
availableActions := make([]appv1.ResourceAction, 0)
if noAvailableActions(jsonBytes) {
return availableActions, nil
}
availableActionsMap := make(map[string]interface{})
err = json.Unmarshal(jsonBytes, &availableActionsMap)
availableActions := make([]appv1.ResourceAction, 0)

for _, script := range script {
l, err := vm.runLua(obj, script)
if err != nil {
return nil, err
}
for key := range availableActionsMap {
value := availableActionsMap[key]
resourceAction := appv1.ResourceAction{Name: key, Disabled: isActionDisabled(value)}
if emptyResourceActionFromLua(value) {
availableActions = append(availableActions, resourceAction)
continue
}
resourceActionBytes, err := json.Marshal(value)
returnValue := l.Get(-1)
if returnValue.Type() == lua.LTTable {
jsonBytes, err := luajson.Encode(returnValue)
if err != nil {
return nil, err
}

err = json.Unmarshal(resourceActionBytes, &resourceAction)
if noAvailableActions(jsonBytes) {
return availableActions, nil
}
availableActionsMap := make(map[string]interface{})
err = json.Unmarshal(jsonBytes, &availableActionsMap)
if err != nil {
return nil, err
}
availableActions = append(availableActions, resourceAction)
for key, value := range availableActionsMap {
resourceAction := appv1.ResourceAction{Name: key, Disabled: isActionDisabled(value)}
if emptyResourceActionFromLua(value) {
availableActions = append(availableActions, resourceAction)
continue
}
resourceActionBytes, err := json.Marshal(value)
if err != nil {
return nil, fmt.Errorf("error marshaling resource action: %w", err)
}

err = json.Unmarshal(resourceActionBytes, &resourceAction)
if err != nil {
return nil, fmt.Errorf("error marshaling resource action: %w", err)
}
availableActions = append(availableActions, resourceAction)
}

} else {
return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String())

}
return availableActions, err
}

return nil, fmt.Errorf(incorrectReturnType, "table", returnValue.Type().String())
return availableActions, nil
}

// Actions are enabled by default
Expand Down Expand Up @@ -346,25 +354,41 @@ func noAvailableActions(jsonBytes []byte) bool {
return string(jsonBytes) == "[]"
}

func (vm VM) GetResourceActionDiscovery(obj *unstructured.Unstructured) (string, error) {
func (vm VM) GetResourceActionDiscovery(obj *unstructured.Unstructured) ([]string, error) {
key := GetConfigMapKey(obj.GroupVersionKind())
var discoveryScripts []string

// Check if there are resource overrides for the given key
override, ok := vm.ResourceOverrides[key]
if ok && override.Actions != "" {
actions, err := override.GetActions()
if err != nil {
return "", err
return nil, err
}
// Append the action discovery Lua script if built-in actions are to be included
if actions.MergeBuiltinActions {
discoveryScripts = append(discoveryScripts, actions.ActionDiscoveryLua)
} else {
return []string{actions.ActionDiscoveryLua}, nil
}
return actions.ActionDiscoveryLua, nil
}

// Fetch predefined Lua scripts
discoveryKey := fmt.Sprintf("%s/actions/", key)
discoveryScript, err := vm.getPredefinedLuaScripts(discoveryKey, actionDiscoveryScriptFile)
if err != nil {
return "", err
return nil, fmt.Errorf("error while fetching pre defined lua scripts: %w", err)
}

// Append or return the discovery script based on the presence of built-in actions
if len(discoveryScripts) > 0 {
discoveryScripts = append(discoveryScripts, discoveryScript)
} else {
return []string{discoveryScript}, nil
}
return discoveryScript, nil
}

// GetResourceAction attempts to read lua script from config and then filesystem for that resource
return discoveryScripts, nil
} // GetResourceAction attempts to read lua script from config and then filesystem for that resource
func (vm VM) GetResourceAction(obj *unstructured.Unstructured, actionName string) (appv1.ResourceActionDefinition, error) {
key := GetConfigMapKey(obj.GroupVersionKind())
override, ok := vm.ResourceOverrides[key]
Expand Down

0 comments on commit f1aa48e

Please sign in to comment.