Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(design_proposal): chef cli catalog #877

Merged
merged 15 commits into from
Feb 21, 2020
240 changes: 240 additions & 0 deletions docs/Chef-CLI-Catalog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
# Chef CLI (Catalog)

Throughout the history of Chef, we have created and acquired a variety
of tools that have grown to a point that, as a Chef Operator, it is
hard to know, discover and understand all of them. A few of the tools
that our users use (almost) every day are:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having a catalog of all available commands/tools is very important. Once the user becomes aware of a tool, the next step is really for them to figure out what it does and if it's useful to them. Is that part of the intended scope of this work? If so then we can collaborate w/ UX team on figuring where/how to display relevant information about each tool and maybe include URLs to more detailed information (e.g. docs page) to users

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is exactly one of the ideas/goals and therefore, collaboration with UX will be required.


* chef (CLI that includes Policyfiles management)
* hab (Habitat CLI)
* inspec
* ohai
* kitchen (Test-kitchen)
* knife
* berks (Berkshelf)
* cookstyle
* delivery
* chef-client
* chef-run/chef-apply
* chef-shell
* chef-solo

Currently, inside the latest version of Chef Workstation (and since version `0.10.41`),
the team has implemented a top-level `chef` command that acts as a wrapper around chef
commands. In this design proposal we expand this scope to be a proxy/catalog of all the
user facing cli tools we package inside Chef Workstation.

Quick diagram that illustrates the new Chef CLI Catalog:

![chef-cli-catalog](img/chef-top-level-command.jpg)

With this architecture, we would be able to integrate and modularize multiple tools
in a single place and make the chef command a first-class citizen of our development
experience. We will also be able to gather immediate information from our users of
all our tools so we can understand what parts of our tooling are the most used and
which areas can we improve.

Once detecting such areas of improvement, we can have the flexibility to improve
tools entirely or sub-sections of the tool. Say for instance, that our users run
`knife search` around 30-50 times a day, if the command takes around 10-15
seconds to run, we are consuming ~10 minutes a day from our users waiting for value.
With this approach we could rewrite that specific sub-command to run 10x faster and
give that time back to our users.

![mocked-chef-help-command](img/mocked-chef-help-command.png)

[Gist with a few mocked help commands.](https://gist.github.com/afiune/1dc854089002e182288a0452eaa91908)

## Goals
* Have a single, unified way to discover tools to interact with Chef products
* A path to have consistent/usable performance on all supported platforms
* Gather data about how our users consume and interact with our tools (Telemetry)
* Agreement to a common UX standards of our (CLI) tools
* Have the flexibility to rename tools and commands within our ecosystem
* Enable developers to develop tools in any supported programming languages at Chef

## Motivation

As a Chef Operator,
I need a unified Command Line Interface (CLI) that lets me interact with every Chef product,
so I can easly discover the capabilities of the Chef ecosystem.

As a Chef Developer,
I need to be able to gather information about how our users consume and interact with our tools,
so I can identify which commands are used the most and measure the usability and performance on all supported platforms.

## Specification

### Refactor the `chef-cli` (Policyfiles)
With the purpose of having a better sub-command organization, we need to extract
the Policyfile logic out from the `chef-cli` binary. The commands that need to
be extracted are:

```
install Install cookbooks from a Policyfile and generate a locked cookbook set
update Updates a Policyfile.lock.json with latest run_list and cookbooks
push Push a local policy lock to a policy group on the Chef Infra Server
show-policy Show policyfile objects on the Chef Infra Server
diff Generate an itemized diff of two Policyfile lock documents
export Export a policy lock as a Chef Infra Zero code repo
clean-policy-revisions Delete unused policy revisions on the Chef Infra Server
clean-policy-cookbooks Delete unused policyfile cookbooks on the Chef Infra Server
delete-policy-group Delete a policy group on the Chef Infra Server
delete-policy Delete all revisions of a policy on the Chef Infra Server
undelete Undo a delete command
```

The new binary name proposed is `chef-policy` that could initially be the same policyfiles
ruby code that lives inside the `chef-cli`. The rest of the sub-commands will continue to
live inside the `chef-cli` binary.

The new `chef-policy` should contain the following sub-commands:
```
$ chef-policy install
$ chef-policy update
$ chef-policy push (includes push-archive)
$ chef-policy show
$ chef-policy diff
$ chef-policy export
$ chef-policy delete
$ chef-policy undelete
$ chef-policy clean revisions
$ chef-policy clean cookbooks
$ chef-policy group delete (and more? maybe show a policy group)
```
These sub-commands map to the previous top level policy commands. As an example, the
previous command `chef clean-policy-revisions` would map to the new command
`chef-policy clean revisions`.

Once the new `chef-policy` exists, we need to update the `chef` catalog to point to
the new binary and add a section called "Relocated Commands".

The new help command of the `chef` catalog should look like:
```
$ chef
Usage:
chef -h/--help
chef -v/--version
chef command [arguments...] [options...]

Available Commands:
env Prints environment variables used by Chef Workstation
gem Runs the 'gem' command in context of the embedded Ruby
exec Runs the command in context of the embedded ruby
shell-init Initialize your shell to use Chef Workstation as your primary Ruby
generate Generate a new repository, cookbook, or other component
describe-cookbook Prints cookbook checksum information used for cookbook identifier
policy Manage Chef Policyfiles

Renamed Commands:
install Use: chef policy install
update Use: chef policy update
push Use: chef policy push
push-archive Use: chef policy push
show-policy Use: chef policy show
diff Use: chef policy diff
export Use: chef policy export
clean-policy-revisions Use: chef policy clean revisions
clean-policy-cookbooks Use: chef policy clean cookbooks
delete-policy-group Use: chef policy group delete
delete-policy Use: chef policy delete
undelete Use: chef policy undelete

Experimental Commands:
analyze Analyze artifacts from a Chef Infra Server
```

#### Open questions for further discussion with UX:
* How do we want to present these sections? What is the right order?

### Implement Telemetry into the `chef` catalog

To start gathering information from the `chef` catalog we need to create a telemetry
Go library. The design of this work will be captured in a separate document.

### Route tools and binaries through the `chef` catalog

The last thing we propose is routing all our tools and binaries through the `chef`
catalog. An example would be the `hab` and `inspec` binaries that will be routed
as `chef hab` and `chef inspec` accordingly.

The complete output of the `chef` catalog should look like:
```
$ chef
Usage:
chef -h/--help
chef -v/--version
chef command [arguments...] [options...]

Available Commands:
env Prints environment variables used by Chef Workstation
gem Runs the 'gem' command in context of the embedded Ruby
exec Runs the command in context of the embedded ruby
shell-init Initialize your shell to use Chef Workstation as your primary Ruby
generate Generate a new repository, cookbook, or other component
describe-cookbook Prints cookbook checksum information used for cookbook identifier
policy Manage Chef Policyfiles
hab Commands relating to Chef Habitat
inspec Tests and auditing your applications and infrastructure
kitchen Test cookbooks across any combination of platforms and test suites
knife An interface between a local chef-repo and the Chef Infra Server
ohai Collect system configuration data
client Agent that runs locally on every node that is under management by Chef Infra Server
run Execute ad-hoc tasks using Chef
apply Executable program that runs a single recipe
shell A recipe debugging tool that allows the use of breakpoints within recipes
berks Dependency manager for Chef cookbooks
cookstyle Code linting tool that helps you write better Chef Infra cookbooks

Relocated Commands:
install Use now: chef policy install
update Use now: chef policy update
push Use now: chef policy push
push-archive Use now: chef policy push
show-policy Use now: chef policy show
diff Use now: chef policy diff
export Use now: chef policy export
clean-policy-revisions Use now: chef policy clean revisions
clean-policy-cookbooks Use now: chef policy clean cookbooks
delete-policy-group Use now: chef policy group delete
delete-policy Use now: chef policy delete
undelete Use now: chef policy undelete

Experimental Commands:
analyze Analyze artifacts from a Chef Infra Server
```

### Automation of reference documentation

Motivation:

As a technical writer
I want to add examples to the chef catalog documentation
so that users will know the tricky bits and the documentation gets updated automatically as the code evolves

The documentation team is working towards meaningful automation of our reference
documentation, this includes our CLI tools. This proposal includes working with
the documentation team to implement an automation inside our `chef` catalog by
adding long description, platform, and command example fields to the CLI metadata,
as well as fields for position and use examples for flag.

### EXTRA: Present correct usage of sub-binaries

An additional task from this proposal is the use of an environment variable that
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked with Salim about this - IMO, our first implementation should reference chef policy in all the help text. This makes it more confusing for our effortless developers who will directly invoke the chef-policy binary (without all the overhead of the entire Chef Workstation ecosystem). But those are internal users we can help.

In the future I could see us developing a Golang effortless executable that functions similarly to the chef golang executable. It allows us to start creating a custom workflow for them, leveraging tools under the covers that they do not care whether are written in Ruby or Golang. At that time I would introduce some kind of environment variable that would allow the help text to display chef policy or effortless policy.

can control the "Usage" message of sub-binaries. Currently, the `chef-analyze`
binary displays the usage message `chef-analyze [command]` when it is run directly
and also when it is run from the `chef` catalog. We would like the usage message
to be consistent with the way users execute the commands so if you run `chef analyze`
the usage sould be `chef analyze [command]`; and if you run `chef-analyze` the
usage should continue to be `chef-analyze [command]`.

## Open points for further discussion:
* Are we discouraging the use of individual sub-binaries like `knife` or `chef-run`?
* What happens when a user runs a sub-binary without the prefix `chef`?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should not communicate the existence of these binaries to users but we should not prevent their usage. It is just unsupported usage.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I misunderstood this line - I was thinking that we should document chef policy and not document chef-policy but if they run chef-policy we don't do anything to prevent them from doing that.

* How do we capture telemetry on usage when users directly access tools? (EG, `berks`, `inspec` instead of `chef berks`, `chef inspec`)
* How are we communicating deprecations? (UX)
* How are we communicating reorganization of sub-commands? (UX)

## Downstream Impact
* Re organization of Policyfiles commands inside the `chef-cli`
* Effortless will need to point to the new `chef-policy`
Binary file added docs/img/chef-top-level-command.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/mocked-chef-help-command.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.