Skip to content

Commit

Permalink
Feat: initial check command with basic UI (#2)
Browse files Browse the repository at this point in the history
* feat: grant check

grant check adds the ability for the program to take an image or SBOM
and provide a license compliance check based on a provided
configuration

The default configuration denies all licenses so a user running the
command for the first time will see status code 1 as the response

---------

Signed-off-by: Christopher Phillips <[email protected]>
  • Loading branch information
spiffcs authored Nov 16, 2023
1 parent c5e30b5 commit 5782847
Show file tree
Hide file tree
Showing 26 changed files with 2,061 additions and 59 deletions.
62 changes: 47 additions & 15 deletions .binny.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,46 @@ tools:
with:
module: .
entrypoint: cmd/grant

ldflags:
- -X main.version={{ .Version }}
- -X main.gitCommit={{ .Version }}
- -X main.gitDescription={{ .Version }}
# note: sprig functions are available: http://masterminds.github.io/sprig/
- -X main.buildDate={{ now | date "2006-01-02T15:04:05Z07:00" }}
- name: binny
version:
# can be 'main', 'latest', or a specific version
want: v0.3.0
want: v0.6.2
method: github-release
with:
repo: anchore/binny

- name: task
- name: gh
version:
want: v3.30.1
want: v2.35.0
method: github-release
with:
repo: go-task/task
repo: cli/cli

- name: gosimports
- name: quill
version:
want: v0.3.8
want: v0.4.1
method: github-release
with:
repo: rinchsan/gosimports
repo: anchore/quill

- name: golangci-lint
- name: chronicle
version:
want: v1.54.2
want: v0.8.0
method: github-release
with:
repo: golangci/golangci-lint
repo: anchore/chronicle

- name: chronicle
- name: gosimports
version:
want: v0.8.0
want: v0.3.8
method: github-release
with:
repo: anchore/chronicle
repo: rinchsan/gosimports

- name: glow
version:
Expand All @@ -56,3 +60,31 @@ tools:
method: github-release
with:
repo: goreleaser/goreleaser

- name: golangci-lint
version:
want: v1.54.2
method: github-release
with:
repo: golangci/golangci-lint

- name: bouncer
version:
want: v0.1.0
method: github-release
with:
repo: wagoodman/go-bouncer

- name: task
version:
want: v3.30.1
method: github-release
with:
repo: go-task/task

- name: syft
version:
want: v0.95.0
method: github-release
with:
repo: anchore/syft
61 changes: 61 additions & 0 deletions .bouncer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
permit:
- BSD.*
- CC0.*
- MIT.*
- Apache.*
- MPL.*
- ISC
- WTFPL

ignore-packages:
# packageurl-go is released under the MIT license located in the root of the repo at /mit.LICENSE
- github.com/anchore/packageurl-go

# both of these dependencies are specified as Apache-2.0 in their respective GitHub READMEs
- github.com/alibabacloud-go/cr-20160607/client
- github.com/alibabacloud-go/tea-xml/service

# crypto/internal/boring is released under the openSSL license as a part of the Golang Standard Libary
- crypto/internal/boring

# from: https://github.com/spdx/tools-golang/blob/main/LICENSE.code
# The tools-golang source code is provided and may be used, at your option,
# under either:
# * Apache License, version 2.0 (Apache-2.0), OR
# * GNU General Public License, version 2.0 or later (GPL-2.0-or-later).
# (we choose Apache-2.0)
- github.com/spdx/tools-golang

# from: https://github.com/xi2/xz/blob/master/LICENSE
# All these files have been put into the public domain.
# You can do whatever you want with these files.
- github.com/xi2/xz

# from: https://gitlab.com/cznic/sqlite/-/blob/v1.15.4/LICENSE
# This is a BSD-3-Clause license
- modernc.org/libc
- modernc.org/libc/errno
- modernc.org/libc/fcntl
- modernc.org/libc/fts
- modernc.org/libc/grp
- modernc.org/libc/langinfo
- modernc.org/libc/limits
- modernc.org/libc/netdb
- modernc.org/libc/netinet/in
- modernc.org/libc/poll
- modernc.org/libc/pthread
- modernc.org/libc/pwd
- modernc.org/libc/signal
- modernc.org/libc/stdio
- modernc.org/libc/stdlib
- modernc.org/libc/sys/socket
- modernc.org/libc/sys/stat
- modernc.org/libc/sys/types
- modernc.org/libc/termios
- modernc.org/libc/time
- modernc.org/libc/unistd
- modernc.org/libc/utime
- modernc.org/libc/uuid/uuid
- modernc.org/libc/wctype
- modernc.org/mathutil
- modernc.org/memory
2 changes: 2 additions & 0 deletions .chronicle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
enforce-v0: true # don't make breaking-change label bump major version before 1.0.
title: ""
3 changes: 1 addition & 2 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,4 @@ run:
# - structcheck # The owner seems to have abandoned the linter. Replaced by "unused".
# - testpackage
# - varcheck # The owner seems to have abandoned the linter. Replaced by "unused".
# - wsl # this doens't have an auto-fixer yet and is pretty noisy (https://github.com/bombsimon/wsl/issues/90)

# - wsl # this doens't have an auto-fixer yet and is pretty noisy (https://github.com/bombsimon/wsl/issues/90)
6 changes: 3 additions & 3 deletions .grant.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#.grant.yaml
precedence: [deny, allow]
deny: "*"
allow:
deny-licenses: "*"
allow-licenses:
- MIT
- Apache-2
- Apache-2.0
23 changes: 21 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,38 @@ TASK = $(TOOL_DIR)/task
.DEFAULT_GOAL := make-default

## Bootstrapping targets #################################
# note: we need to assume that binny and task have not already been installed
$(BINNY):
@mkdir -p $(TOOL_DIR)
@curl -sSfL https://raw.githubusercontent.com/$(OWNER)/binny/main/install.sh | sh -s -- -b $(TOOL_DIR)

# note: we need to assume that binny and task have not already been installed
.PHONY: task
$(TASK) task: $(BINNY)
$(BINNY) install task
@$(BINNY) install task -q

.PHONY: ci-bootstrap-go
ci-bootstrap-go:
go mod download

# this is a bootstrapping catch-all, where if the target doesn't exist, we'll ensure the tools are installed and then try again
%:
make $(TASK)
$(TASK) $@

## Shim targets #################################

.PHONY: default
default: $(TASK)
@# run the default task in the taskfile
@$(TASK)

# for those of us that can't seem to kick the habit of typing `make ...` lets wrap the superior `task` tool
TASKS := $(shell bash -c "test -f $(TASK) && $(TASK) -l | grep '^\* ' | cut -d' ' -f2 | tr -d ':' | tr '\n' ' '" ) $(shell bash -c "test -f $(TASK) && $(TASK) -l | grep 'aliases:' | cut -d ':' -f 3 | tr '\n' ' ' | tr -d ','")

.PHONY: $(TASKS)
$(TASKS): $(TASK)
@$(TASK) $@

help: $(TASK)
@$(TASK) -l
@$(TASK) -l
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ $ grant check alpine:latest
[return code 1]
```

By default it's configured to deny all licenses out of the box.
```bash
$ grant check alpine.spdx.json
[return code 0]
```

```bash
$ syft -o spdx-json alpine:latest | grant check
[return code 0]
```


## Installation
```bash
Expand All @@ -25,7 +34,15 @@ curl -sSfL https://raw.githubusercontent.com/anchore/grant/main/install.sh | sh

## Usage

The following is an example of a `deny` oriented configuration:
Grant can be used with any OCI image or sbom document to check for license compliance.

By default grant is configured to deny all licenses out of the box.


Grant can be used to deny specific licenses, allowing all others.
It can also be used to allow specific licenses, denying all others.

The following is an example of a `deny` oriented configuration which will deny `*` and allow `MIT` and `Apache-2`:

```yaml
#.grant.yaml
Expand All @@ -36,11 +53,12 @@ allow:
- Apache-2
```
If licenses are found that are not in the allow list grant will return status code 1.
If licenses are found that are not in the allow list, grant will return status code 1.
The IDs that are considered are sourced from the most recent
Valid IDs that are considered are by default sourced from the most recent
[SPDX license list](https://spdx.org/licenses/).
## TODO
In the future it will be possible for users to configure which license list
they would like to use for their `grant check` run.

Expand All @@ -63,3 +81,13 @@ they would like to use for their `grant check` run.
}
[return code 1]
```

## Configuration
```yaml
#.grant.yaml
precedence: [deny, allow]
deny: *
allow:
- MIT
- Apache-2
```
26 changes: 22 additions & 4 deletions cmd/grant/cli/cli.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package cli

import (
"os"

"github.com/anchore/clio"
"github.com/anchore/go-logger"
"github.com/anchore/grant/cmd/grant/cli/command"
"github.com/anchore/grant/cmd/grant/cli/internal/ui"
handler "github.com/anchore/grant/cmd/grant/cli/tui"
"github.com/anchore/grant/internal/bus"
"github.com/anchore/grant/internal/log"
"github.com/anchore/grant/internal/redact"
Expand All @@ -17,13 +21,27 @@ func New(id clio.Identification) clio.Application {
WithGlobalConfigFlag(). // add persistent -c <path> for reading an application config from
WithGlobalLoggingFlags(). // add persistent -v and -q flags tied to the logging config
WithConfigInRootHelp(). // --help on the root command renders the full application config in the help text
WithNoBus().
WithUIConstructor(
// select a UI based on the logging configuration and state of stdin (if stdin is a tty)
func(cfg clio.Config) ([]clio.UI, error) {
noUI := ui.None(cfg.Log.Quiet)
if !cfg.Log.AllowUI(os.Stdin) || cfg.Log.Quiet {
return []clio.UI{noUI}, nil
}
return []clio.UI{
ui.New(cfg.Log.Quiet,
handler.New(handler.DefaultHandlerConfig()),
),
noUI,
}, nil
},
).
WithLoggingConfig(clio.LoggingConfig{
Level: logger.InfoLevel,
Level: logger.ErrorLevel,
}).
WithInitializers(
func(state *clio.State) error {
// clio is setting up and providing the bus, redact store, and logger to the application. Once loaded,
// clio is setting up and providing the redact store, and logger to the application. Once loaded,
// we can hoist them into the internal packages for global use.
bus.Set(state.Bus)
redact.Set(state.RedactStore)
Expand All @@ -42,4 +60,4 @@ func New(id clio.Identification) clio.Application {
// root.AddCommand(command.List(app))

return app
}
}
Loading

0 comments on commit 5782847

Please sign in to comment.