Jac is a GitOps CLI tool and YAML file format for managing and querying your people metadata Source of Truthβ’.
- Defines two CRD-like YAML file formats:
- GitOps-oriented: Your jac "catalog" git repo defines your people metadata, from which you can automate different processes, such as granting access permissions and generating an org chart or a teams page.
- The
jac
CLI allows you to query your catalog in various ways, allowing to quickly answer questions such as:- Who's the front-end developer in the Dragons team?
- How many back-end developers do we have in the organization?
- Who's the manager of the Unicorns team?
- What are the email addresses of all SREs?
- YAML resources are extensible via custom values to address your specific metadata needs.
$ brew tap nestoca/public
$ brew install jac
Upgrade with:
$ brew update
$ brew upgrade jac
Download from GitHub releases and put the binary somewhere in your
$PATH
.
Jac commands will look for a git repo at ~/.jac
and fallback to using current directory as default.
You can override this with the --dir
or -d
flag.
$ git clone git@github.com:<repo-owner>/<catalog-repo>.git ~/.jac
Put a .jacrc
file in your home directory and set the dir
property to the path to your git repo:
dir: /path/to/repo
To get started, clone this repo and have a look at the examples directory, where you will find an example catalog, queries and a GitHub workflow and action for automatically generating a teams pages.
People are the main building blocks of Jac and can be used to model employees, contractors, consultants, etc. They can then be organized into groups to represent your specific organizational structure.
apiVersion: jac.nesto.ca/v1alpha1
kind: Person
metadata:
# Unique ID
name: alice-wonderland
spec:
# Display info
firstName: Alice
lastName: Wonderland
email: alice@example.com
# Groups this person belongs to
groups:
- role-support
- role-manager
- stream-tech-support
# Optional parent person for tree-display / org-chart (eg: manager, team lead...)
parent: jack-sparrow
# Arbitrary custom key-value pairs
values:
githubUser: alicewonderland
Groups can be used to model different concepts such as departments, streams, teams, roles, etc. It's really up to you how you want to use them depending on your organization's needs. Groups do not have to be mutually exclusive, for example a person can belong to multiple teams, streams, and roles.
apiVersion: jac.nesto.ca/v1alpha1
kind: Group
metadata:
# Unique ID
name: team-devops
spec:
# Display info
emoji: π οΈ
fullName: DevOps
email: devops@example.com
# Optional type (eg: stream, team, role, etc) used to filter groups
type: team
# Optional parent group for tree-display
parent: stream-devops
# Arbitrary custom key-value pairs
values:
resourceLabel: devops
You can specify parent groups for a group via its parent
property.
All people belonging to a group automatically inherit all of its parent groups. By default, jac people -g <group>
command will list all people belonging to the specified group or any of its child groups, unless the --immediate
or
-i
flag is specified, in which case only people belonging directly to the specified group will be returned.
That inheritance allows to reduce repetition in your YAML files and keep them DRY. For example, if you have a group
team-sre
with parent stream-devops
, you don't need to explicitly specify stream-devops
as group for all people in
team-sre
, because they will automatically inherit it.
You can optionally specify a type
property for a group, which can then be used to filter groups by type using the
--type
or -T
flag.
However, it is recommended to prefix group names with their type (eg: stream-foo
, team-bar
, role-baz
) and rather
rely on wildcards for filtering them (eg: stream-*
, team-*
, role-*
). The type
property is rather intended for
programmatic processing of YAML files.
$ jac --help
Usage:
jac [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
groups List groups
help Help about any command
people List people
pull Pull git repo
version Display jac version
Flags:
-d, --dir string Directory to search for CRD files (defaults to ~/.jac/repo)
-h, --help help for jac
-y, --yaml Output in YAML format
Use "jac [command] --help" for more information about a command.
Detailed examples for the commands that follow have been documented in a separate README in the example
folder.
$ jac people
$ jac people <person1>,<person2>,...
Use --find
or -f
to find people with free-text search in their first or last name, email or name identifier:
$ jac people --find alice
$ jac people -f alice
Use --group
or -g
to filter by group:
$ jac people --group <group1>,<group2>,...
$ jac people -g <group1>,<group2>,...
Use --hide-groups
or -G
to hide group columns (eg: if your terminal is too narrow):
$ jac people --hide-groups
$ jac people -G
Use --show-names
or -N
to display identifier names instead of full names:
$ jac people --show-names
$ jac people -N
Use --yaml
or -y
to output results as YAML instead of the default table format:
$ jac people --yaml
$ jac people -y
Use --tree
or -t
to output results as YAML instead of the default table format:
$ jac people --tree
$ jac people -t
Use --show-all
or -A
to show all people in tree, highlighting specific people with free-text search:
$ jac people --show-all --tree --find <search>
$ jac people -Atf <search>
Without --show-all
, only people matching the search will be shown, along with their parents.
$ jac people --show-all --tree --group "team-sre"
$ jac people -Atg "team-sre"
$ jac groups
$ jac groups <group1>,<group2>,...
Use --type
to filter by group type:
$ jac groups --type <type1>,<type2>,...
$ jac groups -T <type1>,<type2>,...
$ jac pull
You can use the following syntax to specify the pattern for groups
and people
commands:
- Use
*
to match any number of characters - Specify multiple
,
-separated patterns to match any of them - Specify multiple
&
-separated patterns to match all of them - Force operator evaluation order using parentheses (eg:
(pattern1&pattern2),pattern3
) - Prefix a pattern with
!
to negate it - When including
*
,&
,()
,!
or spaces in patterns, enclose the whole thing in single-quotes to avoid shell issues
You can use the values
property of people and groups to store arbitrary key-value pairs. Those values can then be used programmatically in automated workflows. In the example catalog, streams have resourceLabel
and description
values (used while generating the html page) and people have a githubUser
value.
If you define groups with different type
's, it is recommended to prefix their name with their type, such as stream-foo
,
team-bar
, role-baz
, because:
- It makes it easier to filter groups by type using wildcards (eg:
stream-*
,team-*
,role-*
) - It prevents name collisions between groups of different types
(eg:
stream-devops
,team-devops
androle-devops
).
Leverage directories to organize your groups and people into streams, teams, etc. That structure is
purely for organizational purposes and has no impact on how Jac will treat those groups and people, as long as the
default **/*.yaml
glob expression matches all YAML files.
For example:
βββ roles // roles shared by all streams/teams
β βββ devops.yaml // role-devops
β βββ frontend.yaml // role-frontend
β βββ backend.yaml // role-backend
βββ streams
β βββ product1
β β βββ stream.yaml // stream-product1
β β βββ dragons
β β β βββ team.yaml // team-dragons
β β β βββ alice-wonderland.yaml
β β β βββ ...
β β βββ unicorns
β β β βββ team.yaml // team-unicorns
β β β βββ jack-sparrow.yaml
β β β βββ ...
β β βββ ...
β βββ product2
β βββ ...
βββ devops
β βββ stream.yaml // stream-devops
β βββ sre
β β βββ team.yaml // team-sre
β β βββ ...
β βββ platform
β β βββ team.yaml // team-platform
β β βββ ...
When you run jac
it looks for .jacrc
file in the following locations:
- Directory specified explicitly via
--dir
(or-d
) flag - Current directory
- Your
$HOME
directory - Your
$HOME/.jac
directory
That file is in YAML format and can contain the following properties:
dir: /full/path/to/directory
glob: "**/*.yaml"
The dir
property is optional, can be an absolute path, or be relative to the current
config file's directory. If specified, Jac will use that directory combined with the glob
expression to find and load its YAML files. If not specified, Jac will use the current
config file's directory instead. If Jac finds another config file in that directory, it will
follow the same process over and over until no further config files and directories are found.
The glob
is optional, defaults to **/*.yaml