Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/onelittlenightmusic/opactl
A simple tool for converting Rego (OPA) rule into command.
https://github.com/onelittlenightmusic/opactl
Last synced: 3 months ago
JSON representation
A simple tool for converting Rego (OPA) rule into command.
- Host: GitHub
- URL: https://github.com/onelittlenightmusic/opactl
- Owner: onelittlenightmusic
- License: apache-2.0
- Created: 2022-05-13T07:34:51.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-06-01T02:43:57.000Z (over 2 years ago)
- Last Synced: 2024-07-25T12:52:14.404Z (4 months ago)
- Language: Go
- Homepage:
- Size: 24.7 MB
- Stars: 28
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-opa - opactl - A simple tool to turn your Rego rule into CLI command ([blog](https://itnext.io/implement-a-policy-and-use-it-in-cli-de906237c6ab)) (Tools and Utilities / Testing Blogs and Articles)
README
# opactl
`opactl` executes your own Rego (OPA) policy as CLI command.
This is how it works. You define a rule in OPA policy, for example `rule1`. Then, `opactl` detects your rule and turns it into subcommand such as `opactl rule1`. It also supports completion with `tab` key.
Options are supported for various usage. Also, you can preset configuration file, then `opactl` reads it.
## Prerequisite
- CLI `opa` is used in `opactl`. You can install `opa` following [Running OPA](https://www.openpolicyagent.org/docs/latest/#running-opa).
## Execute a rule as subcommand
When you define a rule `filter` as follows,
```rego
package opactl# pick up only lines which includes specific mod
filter = { line |
# load each line of stdin
line := input.stdin[_]
# split into words
texts := split(texts, " ")
# check the first word equals to parameter `mod`
texts[0] == input.mod
}
```you can run a subcommand `opactl filter` like this.
```sh
# Run subcommand filter with using stdin (-i) and parameter (mod=...)
ls -l | opactl -i examples filter filter -p mod="-rwxr-xr-x"
[
"-rwxr-xr-x 1 hiroyukosaki staff 8055840 May 12 01:04 opactl"
]
```In another case, JSON can be read. ([examples/filter.rego](examples/filter.rego))
```sh
echo '{"orange": {"sweetness": "high"}, "cherry": {"sweetness":"middle"}}' | opactl -i examples filter json_filter -p sweetness=high
[
"orange"
]
```Last, `opactl` is good for use with other commands ([Script examples](examplescripts))
## Installation
Build from source
```sh
git clone https://github.com/onelittlenightmusic/opactl
cd opactl
go build
sudo cp opactl /usr/local/bin/
```### Enable shell completion
```sh
# bash
source <(opactl completion bash)
# zsh
opactl completion zsh > /usr/local/share/zsh/site-functions/_opactl
````opactl` autocompletes the subcommands.
```sh
opactl
hierarchy visibility ..(as many rules as you define)
```## Give it a try!
After the installation, you can learn how to use `opactl` with examples in the repository (example rules are located [here](examples)).
```sh
opactl examples help
```## Options
```
Flags:
-a, --all Show all commands
-B, --base string OPA base path which will be evaluated (default "data.opactl")
-b, --bundle strings bundles
--config string config file (default is /.opactl)
-d, --directory strings directories
-h, --help help for opactl
-p, --parameter strings Parameter (-p key=value[,key2=value2] [-p others])
-P, --parameter-array stringArray Array parameter (key=value1,value2 [key=value3])
-q, --query string Input your own query script (example: { rtn | rtn := 1 })
-r, --raw-output If the result of rule is a string,
it will be written directly to stdout without quotes
-i, --stdin Accept stdin as input.stdin.
Multiple lines are stored as array.
JSON will be parsed and stored in input.json_stdin as well.
-v, --verbose Toggle verbose mode on/off (display print() output)
```Usage example)
```sh
opactl -a
# all rules should be listed.
[
"filter",
"hierarchy",
"visibility"
]
```## Configuration
You can create an `.opactl` configuration file. When you run `opactl` command in the same directory, `opactl` loads the configuration and set options.
Each field in `.opactl` is connected to one option. For example, `parameter` field is read as `--parameter` option.
```
directory:
- examples
base: data.opactl
parameter:
- item=1
```## Define your rule
- [Rules - Policy Language (Open Policy Agent)](https://www.openpolicyagent.org/docs/latest/policy-language/#rules)
- Rules are virtual document in OPA. Rules allows users to generate objects, sets, arrays, functions and so on.```rego
# object
get_test_object = {
"test": "test"
}get_first_line = rtn {
rtn := input.stdin[0]
} else = {}
# To define default return value is strongly recommended.# set (Kind of list. Elements are unique. No order.)
select_unique_lines[rtn] {
rtn := input.stdin[_]
}# array (Kind of list. Elements are not necessary unique. The order is preserved.)
lines = [rtn|
rtn := input.stdin[_]
]```
## Advanced techniques
### 1. Shorthand of subcommand
If you have `cmd1` subcommand, you can create shorthand `c1` by adding the last one line.
```rego
package opactlcmd1 = ...
c1 = cmd1
```We can execute shorthand like this.
```sh
opactl c1 (= opactl cmd1)
```### 2. Hierarchy of subcommand/subsubcommand and so on
- **Subcommand**
You can create subcommand `opactl cmd1` by creating a rule `cmd1`.
- **Subsubcommand**when you need subsubcommand `opactl cmd2 cmd21` under the subcommand `opactl cmd2`, you can create a package `package opactl.cmd2` and create a rule `cmd21` under this package.
- **Subsubsubcommand**We can create subsubsubcommand such as `opactl cmd2 cmd22 cmd221` in the same way by creating `package opactl.cmd2.cmd22`.
Let's compare these hierarchical patterns.
```
package opactl
├── rule cmd1 (this works as `opactl cmd1`)
├── package opactl.cmd2
│ ├── rule cmd21 (this works as `opactl cmd2 cmd21`)
│ └── package opactl.cmd2.cmd22
│ └── rule cmd221 (this works as `opactl cmd2 cmd22 cmd221`)
```### 3. Supecial command for relative path
`.` and `..` are supported to get all data in current path and parent path respectively.
```sh
opactl . (= show base path data.opactl)
opactl lines .. (=show base path data.opactl, which is parent of lines)
```### 4. Description for completion
You can define a description for each subcommand.
When you trigger subcommand completion, each option can have a description. For example, subcommand `visibility` has a description `Example of how to use invisible field...`.
```sh
$ opactl
completion -- Generate completion script
filter -- Filter ls output with mode label (parameter mod="-rwxr-xr-x")
help -- Help about any command
visibility -- Example of how to use invisible field __ and comments
```Descriptions can be written as `__comment` under a package, or `__` next to a field.
([Example](./examples/visibility.rego))```rego
package opactl.visibility# A comment for subcommand "visibility"
__comment = "Example of how to use invisible field __ and comments"# A comment for subsubcommand "artist"
__artist = "Get data from __config field"
artist = __config.artist# A comment for subsubcommand "song_id"
__song_id = "Get id of song"
song_id = 1# A comment for subsubcommand "song"
__song = "Get a song specified with song_id"
song = __config.songs[song_id]
```Example) Outputs of completion
![](img/2022-05-22-14-00-33.png)
![](img/2022-05-22-13-59-59.png)